开发者

Chrome Extension: popup.html dynamically create via contentscript.js

开发者 https://www.devze.com 2023-01-26 05:15 出处:网络
I\'ve read Google\'s Message passing page and I\'ve also read similar questions here on StackOverflow.

I've read Google's Message passing page and I've also read similar questions here on StackOverflow.

The full source for what I am working on is available on google code.

I right now have the contentscript.js insert links next to dates on a webpage that directs the user to Google's calendar event creation page with the date/time already filled out.

contentscript.js

    /*
 * Copyright (c) 2010 Thomas Wolfe. All rights reserved.  Use of this
 * source code is governed by a Simplified BSD license that can be found in the
 * LICENSE file.
 */
/*
 * Regex Matches
 * 12/31/2002     | Dec 31, 2002 | December 31 2002 | 12-31-2002 | 2002/12/31 (ISO 8601) | 12/31/2002 20:00 | 12/31/2002 08:00 PM
 * Non-Matches
 * 12/31/02  | 15/12/2002 (day month year) | 2002/12/3 (needs a two digit day in this case to prevent breaking 2 digit day)
 */
var regex = /(((([0]?[1-9]|1[0-2])|(Jan|January|Feb|February|Mar|March|Apr|April|May|Jun|June|Jul|July|Aug|August|Sep|September|Oct|October|Nov|November|Dec|December))(\/|-|\.| |, )([0-2]?[0-9]|3[0-1])(\/|-|\.| |, )([1-2]\d{3}))|(([1-2]\d{3})(\/|-|\.| |, )(([0]?[1-9]|1[0-2])|(Jan|January|Feb|February|Mar|March|Apr|April|May|Jun|June|Jul|July|Aug|August|Sep|September|Oct|October|Nov|November|Dec|December))(\/|-|\.| |, )([0-2]?[0-9]|3[0-1]){2}))( (([0-1]?\d)|(2[0-3])):[0-5]\d)?( AM| am| PM| pm)?/ig;
// Removes duplicate values from an array
function unique(inputArray){
    var outputArray = new Array();
    o: for (var i = 0; i < inputArray.length; i++) {
        for (var x = 0; x < outputArray.length; x++) {
            if (outputArray[x] == inputArray[i]) 
                continue o;
        }
        outputArray[outputArray.length] = inputArray[i];
    }
    return outputArray;
}

// Converts the given time into UTC, returns this in a string
function getUTCDateString(y, m, d, h, min){
    var timeObj = new Date(y, m - 1, d, h, min);
    var dateStr = "" + timeObj.getUTCFullYear();
    dateStr += stringPad(timeObj.getUTCMonth() + 1);
    dateStr += stringPad(timeObj.getUTCDate());
    dateStr += "T" + stringPad(timeObj.getUTCHours());
    dateStr += stringPad(timeObj.getUTCMinutes()) + "00Z";
    return dateStr;
}

// Add a leading '0' if string is only 1 char
function stringPad(str){
    var newStr = "" + str;
    if (newStr.length == 1) {
        newStr = "0" + newStr;
    }
    return newStr;
}

function getMonthByName(str){
    var newStr = "" + str;
    var month;
    switch (newStr) {
        case "Jan":
        case "January":
            month = 1;
            break;
        case "Feb":
        case "February":
            month = 2;
            break;
        case "Mar":
        case "March":
            month = 3;
            break;
        case "Apr":
        case "April":
            month = 4;
            break;
        case "May":
            month = 5;
            break;
        case "Jun":
        case "June":
            month = 6;
            break;
        case "Jul":
        case "July":
            month = 7;
            break;
        case "Aug":
        case "August":
            month = 8;
            break;
        case "Sep":
        case "September":
            month = 9;
            break;
        case "Oct":
        case "October":
            month = 10;
            break;
        case "Nov":
        case "November":
            month = 11;
            break;
        default:
            month = 12;
    }
    return month;
}

function indiciesOfText(stringToSearch, searchFor)
{
 var regex = new RegExp(searchFor,"g"), result, indices = [];
 while ( (result = regex.exec(stringToSearch)) ) {
     indices.push(result.index+searchFor.length);
 }
 return indices;
}
function createLinkImg(dateStr)
{
 var dateImg = document.createElement("IMG");
 dateImg.title = "Add this event to your Google Calendar";
 dateImg.src = chrome.extension.getURL("Config-date-16.png")
 var dateLink = document.createElement("A");
 dateLink.target = "_blank";
 dateLink.href = "http://www.google.com/calendar/event?action=TEMPLATE&text=someevent&dates=" + dateStr + "&details=&location=&trp=false&sprop=&sprop=";
 dateLink.appendChild(dateImg);
 return dateLink;
}
function replaceText(dateStr, dateTxt, tobeReplacedNode) {
 dateLink = createLinkImg(dateStr);
 // if textNode search and replace
 if (tobeReplacedNode.nodeType == 3) {
  if (tobeReplacedNode.textContent.search(new RegExp(dateTxt,"g")) != -1) {
   var splitTxtNode = indiciesOfText(tobeReplacedNode.textContent,dateTxt);
   for (var k = 0; k < splitTxtNode.length; k++) {
    if (k == 0) {
     var txtAfterOffsetNode = tobeReplacedNode.splitText(splitTxtNode[k]);
     tobeReplacedNode.parentNode.insertBefore(dateLink, tobeReplacedNode.nextSibling);
    }
    else {
     var txtAfterOffsetNode = txtAfterOffsetNode.splitText(splitTxtNode[k]-splitTxtNode[k-1]);
     txtAfterOffsetNode.parentNode.insertBefore(dateLink, txtAfterOffsetNode.nextSibling);
    }
   }
  }
 }
 if (tobeReplacedNode.hasChildNodes() && splitTxtNode == null) {
  //recall this function
  for (var j = 0; j < tobeReplacedNode.childNodes.length; j++) {
   replaceText(dateStr, dateTxt, tobeReplacedNode.childNodes[j]);
  }
 }
 //return tobeReplacedNode;
}
function getMonthDayYearHourMin(date) {
 var arraySplits = date.split(/(\/|-|\.| |, |:)/gi);

 // set time (hour/min)
 if (arraySplits.length > 5) {
  hour = arraySplits[6];
  min = arraySplits[8];
  if (arraySplits.length > 9) {
   ampm = arraySplits[10];
   if (ampm == "pm" | "PM") {
    hour = 12 + parseInt(hour);
    hour = hour.toString();
   }
  }
 }
 else // no time provided, set to 00:00
 {
  hour = "00";
  min = "00";
 }
 // if the year is not the first element day/year/month are in different locations
 if (arraySplits[0].length != 4 | (arraySplits[0] == "June" | "July")) {
  year = arraySplits[4];

  if (parseInt(arraySplits[0]) > 12) {
   if (arraySplits[2].length < 3) {
    month = arraySplits[2];
   }
   else {
    month = getMonthByName(arraySplits[2]);
   }
   day = arraySplits[0];
  }
  if (arraySplits[0].length < 3) {
   month = arraySplits[0];
  }
  else {
   month = getMonthByName(arraySplits[0]);
  }
  day = arraySplits[2];
 }
 else {
  year = arraySplits[0];
  if (parseInt(arraySplits[2]) > 12) {
   day = arraySplits[2];
   month = arraySplits[4];
  }
  else {
   month = arraySplits[2];
   day = arraySplits[4];
  }
 }
 return getUTCDateString(year, month, day, hour, min);
}
function replaceBody(date, bodyElement) {
 initDateString = getMonthDayYearHourMin(date);
    dateString = initDateString + "/" + initDateString;

 replaceText(dateString, date, bodyElement);
 return dateString;
}

// Test the text of the body element against our regular expression.
if (regex.test(document.body.innerText)) {
    var bodyElement = document.getElementsByTagName("BODY")[0];
    var nonUniqueArrayDates = document.body.innerText.match(regex); // array of date/time values
    var arrayDates = unique(nonUniqueArrayDates);
 var arrayDateStr = new Array();

 // FIXME: ugly hack for this for loop to deal with issue 9 which I cannot figure out
 for (var i = 0; i < Math.min(arrayDates.length,20); i++) {
  arrayDateStr.push(replaceBody(arrayDates[i], bodyElement));
 }
 /* The regular expression produced a match, so notify the background page
  * and send the array of dateStrings.
  */
    chrome.extension.sendRequest({dates: JSON.stringify(arrayDateStr)}, function(response){
    });
}
else {
    // No match was found.
}

I also have the contentscript send a request to the background.html page to show the page_action button.

background.html:

    <!DOCTYPE html>
<!--
 * Copyright (c) 2010 The Chromium Authors. All rights reserved.  Use of this
 * source code is governed by a BSD-style license that can be found in the
 * LICENSE file.
-->
<html>
  <head>
    <script>
      // Called when a message is passed.  We assume that the content script
      // wants to show the page action.
      function onRequest(request, sender, sendResponse) {
        // Show the page action for the tab that the sender (content script)
        // was on.
        chrome.pageAction.show(sender.tab.id);
  var arrayDateStr = JSON.parse(request.dates);
        // Return nothing to let the connection be cleaned up.
        sendResponse({});
      };

      // Listen for the content script to send a message to the background page.
      chrome.extension.onRequest.addListener(onRequest);

   // Google Analytics, registers a view once per browser session
   var _gaq = _gaq || [];
     _gaq.push(['_setAccount', 'UA-2551829-4']);
     _gaq.push(['_trackPageview']);

     (function() {
       var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
       ga.src = 'https://ssl.google-analytics.com/ga.js';
       var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
     })();
    </script>
  </head>
</html>

I'm now trying to create a popup.html which contains a list of all of the dates on a webpage and again a link to create an event in the users calendar.

popup.html

<head>
<style>
body {
  margin: 0px;
  padding: 0px;
}
#cal {
  width: 312px;
  height: 312px;
}
</style>
<script>
function createLink(dateStr)
{
 var parElem = document.createElement("P");
 var textNode = document.createTextNode(dateStr);
 var dateLink = document.createElement("A");
 dateLink.target = "_blank";
 dateLink.href = "http://www.google.com/calendar/event?action=TEMPLATE&text=someevent&dates=" + dateStr + "&details=&location=&trp=false&sprop=&sprop=";
 dateLink.appendChild(textNode);
 parElem.appendChild(dateLink);
 return parElem;
}
function cal() {
  var arrayDateStr = chrome.extension.getBackgroundPage().arrayDateStr;
  var cal = document.getElementById("cal");
  for(i=0; i<arrayDateStr.length; i++)
  {
   cal.appendChild(createLink(arrayDateStr[i]));
  }
}
</script>
</h开发者_开发知识库ead>
<body onload="cal()">
<p id="cal"></p>
</body>

For some reason var arrayDateStr = chrome.extension.getBackgroundPage().arrayDateStr; arrayDateStr does not seem to ever be defined.

I'm just really confused right now and cannot find any examples that I understand. I'm thinking I need to do something else with message passing because I don't think getBackgroundPage() would know which tab it should be associated with.

Any ideas or suggestions would be appreciated. Thank you.


I figured it out, sorry if I wasted anyones time. I had to move var arrayDateStr = null; before the onRequest function in background.html Hopefully this may help someone in the future.

very minor change:

    <!DOCTYPE html>
<!--
 * Copyright (c) 2010 The Chromium Authors. All rights reserved.  Use of this
 * source code is governed by a BSD-style license that can be found in the
 * LICENSE file.
-->
<html>
  <head>
    <script>
      var arrayDateStr = null;
      // Called when a message is passed.  We assume that the content script
      // wants to show the page action.
      function onRequest(request, sender, sendResponse) {
        // Show the page action for the tab that the sender (content script)
        // was on.
        chrome.pageAction.show(sender.tab.id);
        arrayDateStr = JSON.parse(request.dates);
        // Return nothing to let the connection be cleaned up.
        sendResponse({});
      };

      // Listen for the content script to send a message to the background page.
      chrome.extension.onRequest.addListener(onRequest);

      // Google Analytics, registers a view once per browser session
      var _gaq = _gaq || [];
     _gaq.push(['_setAccount', 'UA-2551829-4']);
     _gaq.push(['_trackPageview']);

     (function() {
       var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
       ga.src = 'https://ssl.google-analytics.com/ga.js';
       var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
     })();
    </script>
  </head>
</html>
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号