WooCommerce PDF Invoices & Packing Slips - Version 1.1.3

Version Description

  • Feature: PDF engine (dompdf) updated to 0.6.0 for better stability and utf-8 support.
  • Tweak: Local server path is used for header image for better compatibility with server settings.
  • Fix: several small bugs.
Download this release

Release Info

Developer pomegranate
Plugin Icon 128x128 WooCommerce PDF Invoices & Packing Slips
Version 1.1.3
Comparing to
See all releases

Code changes from version 1.1.2 to 1.1.3

includes/class-wcpdf-export.php CHANGED
@@ -50,6 +50,10 @@ if ( ! class_exists( 'WooCommerce_PDF_Invoices_Export' ) ) {
50
  $this->order = new WC_Order( $order_id );
51
  $template = $this->template_path . '/' . $template_type . '.php';
52
  $output_html[$order_id] = $this->get_template($template);
 
 
 
 
53
  }
54
 
55
  // Try to clean up a bit of memory
@@ -60,7 +64,7 @@ if ( ! class_exists( 'WooCommerce_PDF_Invoices_Export' ) ) {
60
 
61
  // Try to clean up a bit of memory
62
  unset($output_html);
63
-
64
  $template_wrapper = $this->template_path . '/html-document-wrapper.php';
65
  $complete_pdf = $this->get_template($template_wrapper);
66
 
@@ -69,7 +73,7 @@ if ( ! class_exists( 'WooCommerce_PDF_Invoices_Export' ) ) {
69
 
70
  // clean up special characters
71
  $complete_pdf = utf8_decode(mb_convert_encoding($complete_pdf, 'HTML-ENTITIES', 'UTF-8'));
72
-
73
  // die($complete_pdf); //output html to browser for debug
74
 
75
  require_once( WooCommerce_PDF_Invoices::$plugin_path . "lib/dompdf/dompdf_config.inc.php" );
50
  $this->order = new WC_Order( $order_id );
51
  $template = $this->template_path . '/' . $template_type . '.php';
52
  $output_html[$order_id] = $this->get_template($template);
53
+
54
+ // Wipe post from cache
55
+ wp_cache_delete( $order_id, 'posts' );
56
+ wp_cache_delete( $order_id, 'post_meta' );
57
  }
58
 
59
  // Try to clean up a bit of memory
64
 
65
  // Try to clean up a bit of memory
66
  unset($output_html);
67
+
68
  $template_wrapper = $this->template_path . '/html-document-wrapper.php';
69
  $complete_pdf = $this->get_template($template_wrapper);
70
 
73
 
74
  // clean up special characters
75
  $complete_pdf = utf8_decode(mb_convert_encoding($complete_pdf, 'HTML-ENTITIES', 'UTF-8'));
76
+
77
  // die($complete_pdf); //output html to browser for debug
78
 
79
  require_once( WooCommerce_PDF_Invoices::$plugin_path . "lib/dompdf/dompdf_config.inc.php" );
includes/class-wcpdf-settings.php CHANGED
@@ -659,7 +659,7 @@ if ( ! class_exists( 'WooCommerce_PDF_Invoices_Settings' ) ) {
659
  $template_paths = apply_filters( 'wpo_wcpdf_template_paths', $template_paths );
660
 
661
  foreach ($template_paths as $template_source => $template_path) {
662
- $dirs = glob( $template_path . '*' , GLOB_ONLYDIR);
663
 
664
  foreach ($dirs as $dir) {
665
  if ( file_exists($dir."/invoice.php") && file_exists($dir."/packing-slip.php"))
659
  $template_paths = apply_filters( 'wpo_wcpdf_template_paths', $template_paths );
660
 
661
  foreach ($template_paths as $template_source => $template_path) {
662
+ $dirs = (array) glob( $template_path . '*' , GLOB_ONLYDIR);
663
 
664
  foreach ($dirs as $dir) {
665
  if ( file_exists($dir."/invoice.php") && file_exists($dir."/packing-slip.php"))
languages/wpo_wcpdf-nl_NL.mo CHANGED
Binary file
languages/wpo_wcpdf-nl_NL.po CHANGED
@@ -3,7 +3,7 @@ msgstr ""
3
  "Project-Id-Version: WooCommerce PDF Invoices & Packing Slips\n"
4
  "Report-Msgid-Bugs-To: \n"
5
  "POT-Creation-Date: 2014-01-23 12:28+0100\n"
6
- "PO-Revision-Date: 2014-01-23 13:46+0100\n"
7
  "Last-Translator: Ewout Fernhout <chocolade@extrapuur.nl>\n"
8
  "Language-Team: WP Overnight <support@wpovernight.com>\n"
9
  "Language: nl_NL\n"
3
  "Project-Id-Version: WooCommerce PDF Invoices & Packing Slips\n"
4
  "Report-Msgid-Bugs-To: \n"
5
  "POT-Creation-Date: 2014-01-23 12:28+0100\n"
6
+ "PO-Revision-Date: 2014-01-27 12:08+0100\n"
7
  "Last-Translator: Ewout Fernhout <chocolade@extrapuur.nl>\n"
8
  "Language-Team: WP Overnight <support@wpovernight.com>\n"
9
  "Language: nl_NL\n"
lib/dompdf/CONTRIBUTING.md CHANGED
@@ -7,12 +7,14 @@
7
  ## Getting help
8
 
9
  Community discussion, questions, and informal bug reporting is done on the
10
- [dompdf Google group](http://groups.google.com/group/dompdf).
 
 
11
 
12
  ## Submitting bug reports
13
 
14
  The preferred way to report bugs is to use the
15
- [GitHub issue tracker](http://github.com/dompdf/dompdf/issues). Before
16
  reporting a bug, read these pointers.
17
 
18
  **Please search inside the bug tracker to see if the bug you found is not already reported.**
@@ -55,7 +57,8 @@ Questions should be asked on the
55
  - Make sure you have a [GitHub Account](https://github.com/signup/free)
56
  - Fork [dompdf](https://github.com/dompdf/dompdf/)
57
  ([how to fork a repo](https://help.github.com/articles/fork-a-repo))
58
- - Make your changes
 
59
  - Add a simple test file in `www/test/`, with a comprehensive name.
60
  - Submit a pull request
61
  ([how to create a pull request](https://help.github.com/articles/fork-a-repo))
@@ -70,4 +73,4 @@ if ( $foo == "bar" ) {
70
  }
71
  ```
72
  - booleans in lowercase
73
- - opening braces *always* on the same line
7
  ## Getting help
8
 
9
  Community discussion, questions, and informal bug reporting is done on the
10
+ [dompdf Google group](http://groups.google.com/group/dompdf). You may also
11
+ seek help on
12
+ [StackOverflow](http://stackoverflow.com/questions/tagged/dompdf).
13
 
14
  ## Submitting bug reports
15
 
16
  The preferred way to report bugs is to use the
17
+ [GitHub issue tracker](http://github.com/dompdf/dompdf/issues). Before
18
  reporting a bug, read these pointers.
19
 
20
  **Please search inside the bug tracker to see if the bug you found is not already reported.**
57
  - Make sure you have a [GitHub Account](https://github.com/signup/free)
58
  - Fork [dompdf](https://github.com/dompdf/dompdf/)
59
  ([how to fork a repo](https://help.github.com/articles/fork-a-repo))
60
+ - *Make your changes on the dev branch* or the most appropriate feature branch. Please only patch
61
+ the master branch if you are attempting to address an urgent bug in the released code.
62
  - Add a simple test file in `www/test/`, with a comprehensive name.
63
  - Submit a pull request
64
  ([how to create a pull request](https://help.github.com/articles/fork-a-repo))
73
  }
74
  ```
75
  - booleans in lowercase
76
+ - opening braces *always* on the same line
lib/dompdf/dompdf_config.inc.php CHANGED
@@ -8,6 +8,8 @@
8
  * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
9
  */
10
 
 
 
11
  //error_reporting(E_STRICT | E_ALL | E_DEPRECATED);
12
  //ini_set("display_errors", 1);
13
 
@@ -55,7 +57,7 @@ require_once(DOMPDF_INC_DIR . "/functions.inc.php");
55
  * Username and password used by the configuration utility in www/
56
  */
57
  def("DOMPDF_ADMIN_USERNAME", "user");
58
- def("DOMPDF_ADMIN_PASSWORD", "wpovernight");
59
 
60
  /**
61
  * The location of the DOMPDF font directory
@@ -195,7 +197,7 @@ def("DOMPDF_DEFAULT_MEDIA_TYPE", "screen");
195
  *
196
  * @see CPDF_Adapter::PAPER_SIZES for valid sizes
197
  */
198
- def("DOMPDF_DEFAULT_PAPER_SIZE", "a4");
199
 
200
  /**
201
  * The default font family
@@ -203,7 +205,7 @@ def("DOMPDF_DEFAULT_PAPER_SIZE", "a4");
203
  * Used if no suitable fonts can be found. This must exist in the font folder.
204
  * @var string
205
  */
206
- def("DOMPDF_DEFAULT_FONT", "sans-serif");
207
 
208
  /**
209
  * Image DPI setting
@@ -329,7 +331,7 @@ require_once(DOMPDF_LIB_DIR . "/html5lib/Parser.php");
329
  */
330
  if (DOMPDF_ENABLE_AUTOLOAD) {
331
  require_once(DOMPDF_INC_DIR . "/autoload.inc.php");
332
- require_once(DOMPDF_LIB_DIR . "/php-font-lib/classes/font.cls.php");
333
  }
334
 
335
  /**
8
  * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
9
  */
10
 
11
+ if ( class_exists( 'DOMPDF' , false ) ) { return; }
12
+
13
  //error_reporting(E_STRICT | E_ALL | E_DEPRECATED);
14
  //ini_set("display_errors", 1);
15
 
57
  * Username and password used by the configuration utility in www/
58
  */
59
  def("DOMPDF_ADMIN_USERNAME", "user");
60
+ def("DOMPDF_ADMIN_PASSWORD", "password");
61
 
62
  /**
63
  * The location of the DOMPDF font directory
197
  *
198
  * @see CPDF_Adapter::PAPER_SIZES for valid sizes
199
  */
200
+ def("DOMPDF_DEFAULT_PAPER_SIZE", "letter");
201
 
202
  /**
203
  * The default font family
205
  * Used if no suitable fonts can be found. This must exist in the font folder.
206
  * @var string
207
  */
208
+ def("DOMPDF_DEFAULT_FONT", "serif");
209
 
210
  /**
211
  * Image DPI setting
331
  */
332
  if (DOMPDF_ENABLE_AUTOLOAD) {
333
  require_once(DOMPDF_INC_DIR . "/autoload.inc.php");
334
+ require_once(DOMPDF_LIB_DIR . "/php-font-lib/classes/Font.php");
335
  }
336
 
337
  /**
lib/dompdf/include/css_color.cls.php CHANGED
@@ -193,7 +193,7 @@ class CSS_Color {
193
  return $cache[$color] = self::getArray(mb_substr($color, 1, 6));
194
  }
195
 
196
- // rgb( r,g,b ) format
197
  else if ( mb_strpos($color, "rgb") !== false ) {
198
  $i = mb_strpos($color, "(");
199
  $j = mb_strpos($color, ")");
@@ -204,7 +204,18 @@ class CSS_Color {
204
  }
205
 
206
  $triplet = explode(",", mb_substr($color, $i+1, $j-$i-1));
207
-
 
 
 
 
 
 
 
 
 
 
 
208
  if ( count($triplet) != 3 ) {
209
  return null;
210
  }
193
  return $cache[$color] = self::getArray(mb_substr($color, 1, 6));
194
  }
195
 
196
+ // rgb( r,g,b ) / rgbaa( r,g,b,α ) format
197
  else if ( mb_strpos($color, "rgb") !== false ) {
198
  $i = mb_strpos($color, "(");
199
  $j = mb_strpos($color, ")");
204
  }
205
 
206
  $triplet = explode(",", mb_substr($color, $i+1, $j-$i-1));
207
+
208
+ // alpha transparency
209
+ // FIXME: not currently using transparency
210
+ $alpha = 1;
211
+ if ( count( $triplet ) == 4 ) {
212
+ $alpha = (float) ( trim( array_pop( $triplet ) ) );
213
+ // bad value, set to fully opaque
214
+ if ( $alpha > 1 || $alpha < 0 ) {
215
+ $alpha = 1;
216
+ }
217
+ }
218
+
219
  if ( count($triplet) != 3 ) {
220
  return null;
221
  }
lib/dompdf/include/dompdf.cls.php CHANGED
@@ -621,9 +621,14 @@ class DOMPDF {
621
  $quirksmode = ($tokenizer->getTree()->getQuirksMode() > HTML5_TreeBuilder::NO_QUIRKS);
622
  }
623
  else {
 
 
 
 
 
624
  $doc = new DOMDocument();
625
  $doc->preserveWhiteSpace = true;
626
- $doc->loadHTML($str);
627
 
628
  // If some text is before the doctype, we are in quirksmode
629
  if ( preg_match("/^(.+)<!doctype/i", ltrim($str), $matches) ) {
@@ -883,8 +888,25 @@ class DOMPDF {
883
  $this->_pdf->register_string_subset($style->font_family, $chars);
884
  continue;
885
  }
886
-
887
- // TODO Handle other generated content (pseudo elements)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
888
  }
889
  }
890
 
621
  $quirksmode = ($tokenizer->getTree()->getQuirksMode() > HTML5_TreeBuilder::NO_QUIRKS);
622
  }
623
  else {
624
+ // loadHTML assumes ISO-8859-1 unless otherwise specified, but there are
625
+ // bugs in how DOMDocument determines the actual encoding. Converting to
626
+ // HTML-ENTITIES prior to import appears to resolve the issue.
627
+ // http://devzone.zend.com/1538/php-dom-xml-extension-encoding-processing/ (see #4)
628
+ // http://stackoverflow.com/a/11310258/264628
629
  $doc = new DOMDocument();
630
  $doc->preserveWhiteSpace = true;
631
+ $doc->loadHTML( mb_convert_encoding( $str , 'HTML-ENTITIES' , 'UTF-8' ) );
632
 
633
  // If some text is before the doctype, we are in quirksmode
634
  if ( preg_match("/^(.+)<!doctype/i", ltrim($str), $matches) ) {
888
  $this->_pdf->register_string_subset($style->font_family, $chars);
889
  continue;
890
  }
891
+
892
+ // Handle other generated content (pseudo elements)
893
+ // FIXME: This only captures the text of the stylesheet declaration,
894
+ // not the actual generated content, and forces all possible counter
895
+ // values. See notes in issue #750.
896
+ if ( $frame->get_node()->nodeName == "dompdf_generated" ) {
897
+ // all possible counter values
898
+ $chars = List_Bullet_Renderer::get_counter_chars('decimal');
899
+ $this->_pdf->register_string_subset($style->font_family, $chars);
900
+ $chars = List_Bullet_Renderer::get_counter_chars('upper-alpha');
901
+ $this->_pdf->register_string_subset($style->font_family, $chars);
902
+ $chars = List_Bullet_Renderer::get_counter_chars('lower-alpha');
903
+ $this->_pdf->register_string_subset($style->font_family, $chars);
904
+ $chars = List_Bullet_Renderer::get_counter_chars('lower-greek');
905
+ $this->_pdf->register_string_subset($style->font_family, $chars);
906
+ // the text of the stylesheet declaration
907
+ $this->_pdf->register_string_subset($style->font_family, $style->content);
908
+ continue;
909
+ }
910
  }
911
  }
912
 
lib/dompdf/include/frame.cls.php CHANGED
@@ -845,7 +845,7 @@ class Frame {
845
  $this->append_child($new_child, $update_node);
846
  return;
847
  }
848
-
849
  if ( is_null($ref) ) {
850
  $this->prepend_child($new_child, $update_node);
851
  return;
845
  $this->append_child($new_child, $update_node);
846
  return;
847
  }
848
+
849
  if ( is_null($ref) ) {
850
  $this->prepend_child($new_child, $update_node);
851
  return;
lib/dompdf/include/frame_decorator.cls.php CHANGED
@@ -129,11 +129,11 @@ abstract class Frame_Decorator extends Frame {
129
  $frame->set_style(clone $this->_frame->get_original_style());
130
 
131
  $deco = Frame_Factory::decorate_frame($frame, $this->_dompdf, $this->_root);
132
-
133
  foreach ($this->get_children() as $child) {
134
  $deco->append_child($child->deep_copy());
135
  }
136
-
137
  return $deco;
138
  }
139
 
@@ -144,7 +144,7 @@ abstract class Frame_Decorator extends Frame {
144
  $this->_frame->reset();
145
 
146
  $this->_counters = array();
147
-
148
  // Reset all children
149
  foreach ($this->get_children() as $child) {
150
  $child->reset();
@@ -540,15 +540,34 @@ abstract class Frame_Decorator extends Frame {
540
  * @return void
541
  */
542
  function split(Frame $child = null, $force_pagebreak = false) {
 
 
 
 
 
 
543
  if ( is_null( $child ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
544
  $this->get_parent()->split($this, $force_pagebreak);
545
  return;
546
  }
547
-
548
  if ( $child->get_parent() !== $this ) {
549
  throw new DOMPDF_Exception("Unable to split: frame is not a child of this one.");
550
  }
551
-
552
  $node = $this->_frame->get_node();
553
 
554
  $split = $this->copy( $node->cloneNode() );
@@ -573,23 +592,35 @@ abstract class Frame_Decorator extends Frame {
573
  }
574
 
575
  $this->get_parent()->insert_child_after($split, $this);
576
-
577
  // Add $frame and all following siblings to the new split node
578
  $iter = $child;
579
  while ($iter) {
580
- $frame = $iter;
581
  $iter = $iter->get_next_sibling();
582
  $frame->reset();
583
  $split->append_child($frame);
584
  }
585
-
586
  $this->get_parent()->split($split, $force_pagebreak);
 
 
 
 
 
 
587
  }
588
 
589
  function reset_counter($id = self::DEFAULT_COUNTER, $value = 0) {
590
  $this->get_parent()->_counters[$id] = intval($value);
591
  }
592
 
 
 
 
 
 
 
593
  function increment_counters($counters) {
594
  foreach($counters as $id => $increment) {
595
  $this->increment_counter($id, intval($increment));
129
  $frame->set_style(clone $this->_frame->get_original_style());
130
 
131
  $deco = Frame_Factory::decorate_frame($frame, $this->_dompdf, $this->_root);
132
+
133
  foreach ($this->get_children() as $child) {
134
  $deco->append_child($child->deep_copy());
135
  }
136
+
137
  return $deco;
138
  }
139
 
144
  $this->_frame->reset();
145
 
146
  $this->_counters = array();
147
+
148
  // Reset all children
149
  foreach ($this->get_children() as $child) {
150
  $child->reset();
540
  * @return void
541
  */
542
  function split(Frame $child = null, $force_pagebreak = false) {
543
+ // decrement any counters that were incremented on the current node, unless that node is the body
544
+ $style = $this->_frame->get_style();
545
+ if ( $this->_frame->get_node()->nodeName !== "body" && $style->counter_increment && ($decrement = $style->counter_increment) !== "none" ) {
546
+ $this->decrement_counters($decrement);
547
+ }
548
+
549
  if ( is_null( $child ) ) {
550
+ // check for counter increment on :before content (always a child of the selected element @link Frame_Reflower::_set_content)
551
+ // this can push the current node to the next page before counter rules have bubbled up (but only if
552
+ // it's been rendered, thus the position check)
553
+ if ( !$this->is_text_node() && $this->get_node()->hasAttribute("dompdf_before_frame_id") ) {
554
+ foreach($this->_frame->get_children() as $child) {
555
+ if ( $this->get_node()->getAttribute("dompdf_before_frame_id") == $child->get_id() && $child->get_position('x') !== NULL ) {
556
+ $style = $child->get_style();
557
+ if ( $style->counter_increment && ($decrement = $style->counter_increment) !== "none" ) {
558
+ $this->decrement_counters($decrement);
559
+ }
560
+ }
561
+ }
562
+ }
563
  $this->get_parent()->split($this, $force_pagebreak);
564
  return;
565
  }
566
+
567
  if ( $child->get_parent() !== $this ) {
568
  throw new DOMPDF_Exception("Unable to split: frame is not a child of this one.");
569
  }
570
+
571
  $node = $this->_frame->get_node();
572
 
573
  $split = $this->copy( $node->cloneNode() );
592
  }
593
 
594
  $this->get_parent()->insert_child_after($split, $this);
595
+
596
  // Add $frame and all following siblings to the new split node
597
  $iter = $child;
598
  while ($iter) {
599
+ $frame = $iter;
600
  $iter = $iter->get_next_sibling();
601
  $frame->reset();
602
  $split->append_child($frame);
603
  }
604
+
605
  $this->get_parent()->split($split, $force_pagebreak);
606
+
607
+ // If this node resets a counter save the current value to use when rendering on the next page
608
+ if ( $style->counter_reset && ( $reset = $style->counter_reset ) !== "none" ) {
609
+ $vars = preg_split( '/\s+/' , trim( $reset ) , 2 );
610
+ $split->_counters[ '__' . $vars[0] ] = $this->lookup_counter_frame( $vars[0] )->_counters[$vars[0]];
611
+ }
612
  }
613
 
614
  function reset_counter($id = self::DEFAULT_COUNTER, $value = 0) {
615
  $this->get_parent()->_counters[$id] = intval($value);
616
  }
617
 
618
+ function decrement_counters($counters) {
619
+ foreach($counters as $id => $increment) {
620
+ $this->increment_counter($id, intval($increment) * -1);
621
+ }
622
+ }
623
+
624
  function increment_counters($counters) {
625
  foreach($counters as $id => $increment) {
626
  $this->increment_counter($id, intval($increment));
lib/dompdf/include/frame_reflower.cls.php CHANGED
@@ -328,16 +328,15 @@ abstract class Frame_Reflower {
328
  if ( strtolower( $args[1] ) == 'counter' ) {
329
  // counter(name [,style])
330
  if ( isset( $args[5] ) ) {
331
- $type = trim( $args[1] );
332
  }
333
  else {
334
  $type = null;
335
  }
336
-
337
  $p = $this->_frame->lookup_counter_frame( $counter_id );
338
 
339
  $text .= $p->counter_value($counter_id, $type);
340
-
341
  }
342
  else if ( strtolower( $args[1] ) == 'counters' ) {
343
  // counters(name, string [,style])
@@ -347,34 +346,32 @@ abstract class Frame_Reflower {
347
  else {
348
  $string = "";
349
  }
350
-
351
  if ( isset( $args[7] ) ) {
352
  $type = trim( $args[7] );
353
  }
354
  else {
355
  $type = null;
356
  }
357
-
358
  $p = $this->_frame->lookup_counter_frame($counter_id);
359
  $tmp = array();
360
  while ($p) {
361
- // We only want to use the counter values when they actually increment the counter,
362
- // elements that reset the counter, but do not increment it, are skipped.
363
- // FIXME: Is this the best method of determining that an element's counter value should be displayed?
364
- if ( array_key_exists( $counter_id , $p->_counters ) && $p->get_frame()->get_style()->counter_reset == 'none' ) {
365
  array_unshift( $tmp , $p->counter_value($counter_id, $type) );
366
  }
367
  $p = $p->lookup_counter_frame($counter_id);
368
 
369
  }
370
  $text .= implode( $string , $tmp );
371
-
372
  }
373
  else {
374
  // countertops?
375
  continue;
376
  }
377
-
378
  }
379
  else if ( isset($match[4]) && $match[4] !== "" ) {
380
  // String match
@@ -416,7 +413,7 @@ abstract class Frame_Reflower {
416
  }
417
  }
418
  }
419
-
420
  return $text;
421
  }
422
 
@@ -427,9 +424,10 @@ abstract class Frame_Reflower {
427
  $frame = $this->_frame;
428
  $style = $frame->get_style();
429
 
 
430
  if ( $style->counter_reset && ($reset = $style->counter_reset) !== "none" ) {
431
  $vars = preg_split('/\s+/', trim($reset), 2);
432
- $frame->reset_counter($vars[0], isset($vars[1]) ? $vars[1] : 0);
433
  }
434
 
435
  if ( $style->counter_increment && ($increment = $style->counter_increment) !== "none" ) {
@@ -438,6 +436,13 @@ abstract class Frame_Reflower {
438
 
439
  if ( $style->content && !$frame->get_first_child() && $frame->get_node()->nodeName === "dompdf_generated" ) {
440
  $content = $this->_parse_content();
 
 
 
 
 
 
 
441
  $node = $frame->get_node()->ownerDocument->createTextNode($content);
442
 
443
  $new_style = $style->get_stylesheet()->create_style();
328
  if ( strtolower( $args[1] ) == 'counter' ) {
329
  // counter(name [,style])
330
  if ( isset( $args[5] ) ) {
331
+ $type = trim( $args[5] );
332
  }
333
  else {
334
  $type = null;
335
  }
 
336
  $p = $this->_frame->lookup_counter_frame( $counter_id );
337
 
338
  $text .= $p->counter_value($counter_id, $type);
339
+
340
  }
341
  else if ( strtolower( $args[1] ) == 'counters' ) {
342
  // counters(name, string [,style])
346
  else {
347
  $string = "";
348
  }
349
+
350
  if ( isset( $args[7] ) ) {
351
  $type = trim( $args[7] );
352
  }
353
  else {
354
  $type = null;
355
  }
356
+
357
  $p = $this->_frame->lookup_counter_frame($counter_id);
358
  $tmp = array();
359
  while ($p) {
360
+ // We only want to use the counter values when they actually increment the counter
361
+ if ( array_key_exists( $counter_id , $p->_counters ) ) {
 
 
362
  array_unshift( $tmp , $p->counter_value($counter_id, $type) );
363
  }
364
  $p = $p->lookup_counter_frame($counter_id);
365
 
366
  }
367
  $text .= implode( $string , $tmp );
368
+
369
  }
370
  else {
371
  // countertops?
372
  continue;
373
  }
374
+
375
  }
376
  else if ( isset($match[4]) && $match[4] !== "" ) {
377
  // String match
413
  }
414
  }
415
  }
416
+
417
  return $text;
418
  }
419
 
424
  $frame = $this->_frame;
425
  $style = $frame->get_style();
426
 
427
+ // if the element was pushed to a new page use the saved counter value, otherwise use the CSS reset value
428
  if ( $style->counter_reset && ($reset = $style->counter_reset) !== "none" ) {
429
  $vars = preg_split('/\s+/', trim($reset), 2);
430
+ $frame->reset_counter( $vars[0] , ( isset($frame->_counters['__'.$vars[0]]) ? $frame->_counters['__'.$vars[0]] : ( isset($vars[1]) ? $vars[1] : 0 ) ) );
431
  }
432
 
433
  if ( $style->counter_increment && ($increment = $style->counter_increment) !== "none" ) {
436
 
437
  if ( $style->content && !$frame->get_first_child() && $frame->get_node()->nodeName === "dompdf_generated" ) {
438
  $content = $this->_parse_content();
439
+ // add generated content to the font subset
440
+ // FIXME: This is currently too late because the font subset has already been generated.
441
+ // See notes in issue #750.
442
+ if ( $frame->get_dompdf()->get_option("enable_font_subsetting") && $frame->get_dompdf()->get_canvas() instanceof CPDF_Adapter ) {
443
+ $frame->get_dompdf()->get_canvas()->register_string_subset($style->font_family, $content);
444
+ }
445
+
446
  $node = $frame->get_node()->ownerDocument->createTextNode($content);
447
 
448
  $new_style = $style->get_stylesheet()->create_style();
lib/dompdf/include/frame_tree.cls.php CHANGED
@@ -227,13 +227,15 @@ class Frame_Tree {
227
  $parent_id = $node->getAttribute("frame_id");
228
  $parent = $this->get_frame($parent_id);
229
 
230
- if ( $pos === "before" ) {
231
- $parent->prepend_child($frame, false);
232
- }
233
- else {
234
- $parent->append_child($frame, false);
 
 
235
  }
236
-
237
  return $frame_id;
238
  }
239
  }
227
  $parent_id = $node->getAttribute("frame_id");
228
  $parent = $this->get_frame($parent_id);
229
 
230
+ if ( $parent ) {
231
+ if ( $pos === "before" ) {
232
+ $parent->prepend_child($frame, false);
233
+ }
234
+ else {
235
+ $parent->append_child($frame, false);
236
+ }
237
  }
238
+
239
  return $frame_id;
240
  }
241
  }
lib/dompdf/include/functions.inc.php CHANGED
@@ -344,93 +344,121 @@ function parse_data_uri($data_uri) {
344
  /**
345
  * mb_string compatibility
346
  */
347
- if ( !function_exists("mb_strlen") ) {
348
- define('MB_OVERLOAD_MAIL', 1);
349
- define('MB_OVERLOAD_STRING', 2);
350
- define('MB_OVERLOAD_REGEX', 4);
351
- define('MB_CASE_UPPER', 0);
352
- define('MB_CASE_LOWER', 1);
353
- define('MB_CASE_TITLE', 2);
354
-
355
- function mb_convert_encoding($data, $to_encoding, $from_encoding = 'UTF-8') {
356
- if (str_replace('-', '', strtolower($to_encoding)) === 'utf8') {
357
- return utf8_encode($data);
 
 
 
 
358
  }
359
-
360
- return utf8_decode($data);
361
  }
362
 
363
- function mb_detect_encoding($data, $encoding_list = array('iso-8859-1'), $strict = false) {
364
- return 'iso-8859-1';
 
 
365
  }
366
 
367
- function mb_detect_order($encoding_list = array('iso-8859-1')) {
368
- return 'iso-8859-1';
 
 
369
  }
370
 
371
- function mb_internal_encoding($encoding = null) {
372
- if (isset($encoding)) {
373
- return true;
 
 
 
 
374
  }
375
-
376
- return 'iso-8859-1';
377
  }
378
 
379
- function mb_strlen($str, $encoding = 'iso-8859-1') {
380
- switch (str_replace('-', '', strtolower($encoding))) {
381
- case "utf8": return strlen(utf8_encode($str));
382
- case "8bit": return strlen($str);
383
- default: return strlen(utf8_decode($str));
 
 
384
  }
385
  }
386
 
387
- function mb_strpos($haystack, $needle, $offset = 0) {
388
- return strpos($haystack, $needle, $offset);
 
 
389
  }
390
 
391
- function mb_strrpos($haystack, $needle, $offset = 0) {
392
- return strrpos($haystack, $needle, $offset);
 
 
393
  }
394
 
395
- function mb_strtolower( $str ) {
396
- return strtolower($str);
 
 
397
  }
398
 
399
- function mb_strtoupper( $str ) {
400
- return strtoupper($str);
 
 
401
  }
402
 
403
- function mb_substr($string, $start, $length = null, $encoding = 'iso-8859-1') {
404
- if ( is_null($length) ) {
405
- return substr($string, $start);
 
 
 
 
406
  }
407
-
408
- return substr($string, $start, $length);
409
  }
410
 
411
- function mb_substr_count($haystack, $needle, $encoding = 'iso-8859-1') {
412
- return substr_count($haystack, $needle);
 
 
413
  }
414
 
415
- function mb_encode_numericentity($str, $convmap, $encoding) {
416
- return htmlspecialchars($str);
 
 
417
  }
418
 
419
- function mb_convert_case($str, $mode = MB_CASE_UPPER, $encoding = array()) {
420
- switch($mode) {
421
- case MB_CASE_UPPER: return mb_strtoupper($str);
422
- case MB_CASE_LOWER: return mb_strtolower($str);
423
- case MB_CASE_TITLE: return ucwords(mb_strtolower($str));
424
- default: return $str;
 
 
425
  }
426
  }
427
 
428
- function mb_list_encodings() {
429
- return array(
430
- "ISO-8859-1",
431
- "UTF-8",
432
- "8bit",
433
- );
 
 
434
  }
435
  }
436
 
344
  /**
345
  * mb_string compatibility
346
  */
347
+ if (!extension_loaded('mbstring')) {
348
+ def('MB_OVERLOAD_MAIL', 1);
349
+ def('MB_OVERLOAD_STRING', 2);
350
+ def('MB_OVERLOAD_REGEX', 4);
351
+ def('MB_CASE_UPPER', 0);
352
+ def('MB_CASE_LOWER', 1);
353
+ def('MB_CASE_TITLE', 2);
354
+
355
+ if (!function_exists('mb_convert_encoding')) {
356
+ function mb_convert_encoding($data, $to_encoding, $from_encoding = 'UTF-8') {
357
+ if (str_replace('-', '', strtolower($to_encoding)) === 'utf8') {
358
+ return utf8_encode($data);
359
+ }
360
+
361
+ return utf8_decode($data);
362
  }
 
 
363
  }
364
 
365
+ if (!function_exists('mb_detect_encoding')) {
366
+ function mb_detect_encoding($data, $encoding_list = array('iso-8859-1'), $strict = false) {
367
+ return 'iso-8859-1';
368
+ }
369
  }
370
 
371
+ if (!function_exists('mb_detect_order')) {
372
+ function mb_detect_order($encoding_list = array('iso-8859-1')) {
373
+ return 'iso-8859-1';
374
+ }
375
  }
376
 
377
+ if (!function_exists('mb_internal_encoding')) {
378
+ function mb_internal_encoding($encoding = null) {
379
+ if (isset($encoding)) {
380
+ return true;
381
+ }
382
+
383
+ return 'iso-8859-1';
384
  }
 
 
385
  }
386
 
387
+ if (!function_exists('mb_strlen')) {
388
+ function mb_strlen($str, $encoding = 'iso-8859-1') {
389
+ switch (str_replace('-', '', strtolower($encoding))) {
390
+ case "utf8": return strlen(utf8_encode($str));
391
+ case "8bit": return strlen($str);
392
+ default: return strlen(utf8_decode($str));
393
+ }
394
  }
395
  }
396
 
397
+ if (!function_exists('mb_strpos')) {
398
+ function mb_strpos($haystack, $needle, $offset = 0) {
399
+ return strpos($haystack, $needle, $offset);
400
+ }
401
  }
402
 
403
+ if (!function_exists('mb_strrpos')) {
404
+ function mb_strrpos($haystack, $needle, $offset = 0) {
405
+ return strrpos($haystack, $needle, $offset);
406
+ }
407
  }
408
 
409
+ if (!function_exists('mb_strtolower')) {
410
+ function mb_strtolower( $str ) {
411
+ return strtolower($str);
412
+ }
413
  }
414
 
415
+ if (!function_exists('mb_strtoupper')) {
416
+ function mb_strtoupper( $str ) {
417
+ return strtoupper($str);
418
+ }
419
  }
420
 
421
+ if (!function_exists('mb_substr')) {
422
+ function mb_substr($string, $start, $length = null, $encoding = 'iso-8859-1') {
423
+ if ( is_null($length) ) {
424
+ return substr($string, $start);
425
+ }
426
+
427
+ return substr($string, $start, $length);
428
  }
 
 
429
  }
430
 
431
+ if (!function_exists('mb_substr_count')) {
432
+ function mb_substr_count($haystack, $needle, $encoding = 'iso-8859-1') {
433
+ return substr_count($haystack, $needle);
434
+ }
435
  }
436
 
437
+ if (!function_exists('mb_encode_numericentity')) {
438
+ function mb_encode_numericentity($str, $convmap, $encoding) {
439
+ return htmlspecialchars($str);
440
+ }
441
  }
442
 
443
+ if (!function_exists('mb_convert_case')) {
444
+ function mb_convert_case($str, $mode = MB_CASE_UPPER, $encoding = array()) {
445
+ switch($mode) {
446
+ case MB_CASE_UPPER: return mb_strtoupper($str);
447
+ case MB_CASE_LOWER: return mb_strtolower($str);
448
+ case MB_CASE_TITLE: return ucwords(mb_strtolower($str));
449
+ default: return $str;
450
+ }
451
  }
452
  }
453
 
454
+ if (!function_exists('mb_list_encodings')) {
455
+ function mb_list_encodings() {
456
+ return array(
457
+ "ISO-8859-1",
458
+ "UTF-8",
459
+ "8bit",
460
+ );
461
+ }
462
  }
463
  }
464
 
lib/dompdf/include/style.cls.php CHANGED
@@ -868,7 +868,7 @@ class Style {
868
  $this->_parent_font_size = self::$default_font_size;
869
  }
870
 
871
- switch ($fs) {
872
  case "xx-small":
873
  case "x-small":
874
  case "small":
868
  $this->_parent_font_size = self::$default_font_size;
869
  }
870
 
871
+ switch ((string)$fs) {
872
  case "xx-small":
873
  case "x-small":
874
  case "small":
lib/dompdf/include/stylesheet.cls.php CHANGED
@@ -816,8 +816,8 @@ class Stylesheet {
816
 
817
  $query = $this->_css_selector_to_xpath($selector, true);
818
 
819
- // Retrieve the nodes
820
- $nodes = @$xp->query($query["query"]);
821
  if ( $nodes == null ) {
822
  record_warnings(E_USER_WARNING, "The CSS selector '$selector' is not valid", __FILE__, __LINE__);
823
  continue;
@@ -839,7 +839,6 @@ class Stylesheet {
839
  }
840
 
841
  $new_node->setAttribute($pos, $pos);
842
-
843
  $new_frame_id = $tree->insert_node($node, $new_node, $pos);
844
  $node->setAttribute("dompdf_{$pos}_frame_id", $new_frame_id);
845
  }
816
 
817
  $query = $this->_css_selector_to_xpath($selector, true);
818
 
819
+ // Retrieve the nodes, limit to body for generated content
820
+ $nodes = @$xp->query( '.'.$query["query"] );
821
  if ( $nodes == null ) {
822
  record_warnings(E_USER_WARNING, "The CSS selector '$selector' is not valid", __FILE__, __LINE__);
823
  continue;
839
  }
840
 
841
  $new_node->setAttribute($pos, $pos);
 
842
  $new_frame_id = $tree->insert_node($node, $new_node, $pos);
843
  $node->setAttribute("dompdf_{$pos}_frame_id", $new_frame_id);
844
  }
lib/dompdf/include/text_frame_decorator.cls.php CHANGED
@@ -86,7 +86,7 @@ class Text_Frame_Decorator extends Frame_Decorator {
86
  pre_r(($style->line_height / $size) * Font_Metrics::get_font_height($font, $size));
87
  */
88
 
89
- return ($style->line_height / $size) * Font_Metrics::get_font_height($font, $size);
90
 
91
  }
92
 
86
  pre_r(($style->line_height / $size) * Font_Metrics::get_font_height($font, $size));
87
  */
88
 
89
+ return ($style->line_height / ( $size > 0 ? $size : 1 )) * Font_Metrics::get_font_height($font, $size);
90
 
91
  }
92
 
lib/dompdf/lib/class.pdf.php CHANGED
@@ -2335,6 +2335,7 @@ EOT;
2335
  // load the pfb file, and put that into an object too.
2336
  // note that pdf supports only binary format type 1 font files, though there is a
2337
  // simple utility to convert them from pfa to pfb.
 
2338
  if (!$this->isUnicode || $fbtype !== 'ttf' || empty($this->stringSubsets)) {
2339
  $data = file_get_contents($fbfile);
2340
  }
@@ -3491,7 +3492,7 @@ EOT;
3491
 
3492
  /**
3493
  * calculate how wide a given text string will be on a page, at a given size.
3494
- * this can be called externally, but is alse used by the other class functions
3495
  */
3496
  function getTextWidth($size, $text, $word_spacing = 0, $char_spacing = 0) {
3497
  static $ord_cache = array();
@@ -3515,7 +3516,7 @@ EOT;
3515
  $w = 0;
3516
  $cf = $this->currentFont;
3517
  $current_font = $this->fonts[$cf];
3518
- $space_scale = 1000 / $size;
3519
  $n_spaces = 0;
3520
 
3521
  if ( $current_font['isUnicode']) {
2335
  // load the pfb file, and put that into an object too.
2336
  // note that pdf supports only binary format type 1 font files, though there is a
2337
  // simple utility to convert them from pfa to pfb.
2338
+ // FIXME: should we move font subset creation to CPDF::output? See notes in issue #750.
2339
  if (!$this->isUnicode || $fbtype !== 'ttf' || empty($this->stringSubsets)) {
2340
  $data = file_get_contents($fbfile);
2341
  }
3492
 
3493
  /**
3494
  * calculate how wide a given text string will be on a page, at a given size.
3495
+ * this can be called externally, but is also used by the other class functions
3496
  */
3497
  function getTextWidth($size, $text, $word_spacing = 0, $char_spacing = 0) {
3498
  static $ord_cache = array();
3516
  $w = 0;
3517
  $cf = $this->currentFont;
3518
  $current_font = $this->fonts[$cf];
3519
+ $space_scale = 1000 / ( $size > 0 ? $size : 1 );
3520
  $n_spaces = 0;
3521
 
3522
  if ( $current_font['isUnicode']) {
lib/dompdf/lib/php-font-lib/.gitattributes DELETED
@@ -1,12 +0,0 @@
1
- *.json text
2
- *.xml text
3
- *.php text
4
- *.LGPL text
5
- *.md text
6
- *.skel text
7
- *.css text
8
- *.inc text
9
- *.js text
10
- *.html text
11
- *.txt text
12
- *.svg text
 
 
 
 
 
 
 
 
 
 
 
 
lib/dompdf/lib/php-font-lib/.gitignore DELETED
@@ -1,5 +0,0 @@
1
- .DS_Store
2
- composer.lock
3
- vendor
4
- .idea
5
- .project
 
 
 
 
 
lib/dompdf/lib/php-font-lib/classes/Font_Glyph_Outline.php CHANGED
@@ -7,9 +7,6 @@
7
  * @version $Id: Font_Table_glyf.php 46 2012-04-02 20:22:38Z fabien.menager $
8
  */
9
 
10
- require_once dirname(__FILE__) . "/Font_Glyph_Outline_Simple.php";
11
- require_once dirname(__FILE__) . "/Font_Glyph_Outline_Composite.php";
12
-
13
  /**
14
  * `glyf` font table.
15
  *
@@ -104,4 +101,7 @@ class Font_Glyph_Outline extends Font_Binary_Stream {
104
  function getGlyphIDs(){
105
  return array();
106
  }
107
- }
 
 
 
7
  * @version $Id: Font_Table_glyf.php 46 2012-04-02 20:22:38Z fabien.menager $
8
  */
9
 
 
 
 
10
  /**
11
  * `glyf` font table.
12
  *
101
  function getGlyphIDs(){
102
  return array();
103
  }
104
+ }
105
+
106
+ require_once dirname(__FILE__) . "/Font_Glyph_Outline_Simple.php";
107
+ require_once dirname(__FILE__) . "/Font_Glyph_Outline_Composite.php";
lib/dompdf/www/cssSandpaper/css/reset.css DELETED
@@ -1,66 +0,0 @@
1
- /*
2
- * CSS Reset based on code from
3
- * http://meyerweb.com/eric/thoughts/2007/05/01/reset-reloaded/
4
- *
5
- * Earlier copy stated:
6
- * "If you want to use my reset styles, then feel free! It's all
7
- * explicitly in the public domain (I have to formally say that
8
- * or else people ask me about licensing)."
9
- */
10
-
11
- html, body, div, span, applet, object, iframe,
12
- h1, h2, h3, h4, h5, h6, p, blockquote, pre,
13
- a, abbr, acronym, address, big, cite, code,
14
- del, dfn, em, font, img, ins, kbd, q, s, samp,
15
- small, strike, strong, sub, sup, tt, var,
16
- dl, dt, dd, ol, ul, li,
17
- fieldset, form, label, legend,
18
- table, caption, tbody, tfoot, thead, tr, th, td {
19
- margin: 0;
20
- padding: 0;
21
- border: 0;
22
- outline: 0;
23
- font-weight: inherit;
24
- font-style: inherit;
25
- font-size: 100%;
26
- font-family: inherit;
27
- vertical-align: baseline;
28
- }
29
- /* remember to define focus styles! */
30
- :focus {
31
- outline: 0;
32
- }
33
- body {
34
- line-height: 1;
35
- color: black;
36
- background: white;
37
- }
38
- ol, ul {
39
- list-style: none;
40
- }
41
- /* tables still need 'cellspacing="0"' in the markup */
42
- table {
43
- border-collapse: separate;
44
- border-spacing: 0;
45
- }
46
- caption, th, td {
47
- text-align: left;
48
- font-weight: normal;
49
- }
50
- blockquote:before, blockquote:after,
51
- q:before, q:after {
52
- content: "";
53
- }
54
- blockquote, q {
55
- quotes: "" "";
56
- }
57
-
58
- /*
59
- * Added 2009/02/04 to fix IE7's issue with interpolated
60
- * scaling not turned on by default. Based on an idea from
61
- * http://acidmartin.wordpress.com/2009/01/05/better-image-scaling-and-resampling-in-internet-explorer/
62
- */
63
- img
64
- {
65
- -ms-interpolation-mode: bicubic;
66
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/dompdf/www/cssSandpaper/js/EventHelpers.js DELETED
@@ -1,441 +0,0 @@
1
- /*******************************************************************************
2
- * This notice must be untouched at all times.
3
- *
4
- * This javascript library contains helper routines to assist with event
5
- * handling consinstently among browsers
6
- *
7
- * EventHelpers.js v.1.3 available at http://www.useragentman.com/
8
- *
9
- * released under the MIT License:
10
- * http://www.opensource.org/licenses/mit-license.php
11
- *
12
- *******************************************************************************/
13
- var EventHelpers = new function(){
14
- var me = this;
15
-
16
- var safariTimer;
17
- var isSafari = /WebKit/i.test(navigator.userAgent);
18
- var globalEvent;
19
-
20
- me.init = function () {
21
- if (me.hasPageLoadHappened(arguments)) {
22
- return;
23
- }
24
-
25
- if (document.createEventObject){
26
- // dispatch for IE
27
- globalEvent = document.createEventObject();
28
- } else if (document.createEvent) {
29
- globalEvent = document.createEvent("HTMLEvents");
30
- }
31
-
32
- me.docIsLoaded = true;
33
- }
34
-
35
- /**
36
- * Adds an event to the document. Examples of usage:
37
- * me.addEvent(window, "load", myFunction);
38
- * me.addEvent(docunent, "keydown", keyPressedFunc);
39
- * me.addEvent(document, "keyup", keyPressFunc);
40
- *
41
- * @author Scott Andrew - http://www.scottandrew.com/weblog/articles/cbs-events
42
- * @author John Resig - http://ejohn.org/projects/flexible-javascript-events/
43
- * @param {Object} obj - a javascript object.
44
- * @param {String} evType - an event to attach to the object.
45
- * @param {Function} fn - the function that is attached to the event.
46
- */
47
- me.addEvent = function(obj, evType, fn){
48
-
49
- if (obj.addEventListener) {
50
- obj.addEventListener(evType, fn, false);
51
- } else if (obj.attachEvent) {
52
- obj['e' + evType + fn] = fn;
53
- obj[evType + fn] = function(){
54
- obj["e" + evType + fn](self.event);
55
- }
56
- obj.attachEvent("on" + evType, obj[evType + fn]);
57
- }
58
- }
59
-
60
-
61
- /**
62
- * Removes an event that is attached to a javascript object.
63
- *
64
- * @author Scott Andrew - http://www.scottandrew.com/weblog/articles/cbs-events
65
- * @author John Resig - http://ejohn.org/projects/flexible-javascript-events/ * @param {Object} obj - a javascript object.
66
- * @param {String} evType - an event attached to the object.
67
- * @param {Function} fn - the function that is called when the event fires.
68
- */
69
- me.removeEvent = function(obj, evType, fn){
70
-
71
- if (obj.removeEventListener) {
72
- obj.removeEventListener(evType, fn, false);
73
- } else if (obj.detachEvent) {
74
- try {
75
- obj.detachEvent("on" + evType, obj[evType + fn]);
76
- obj[evType + fn] = null;
77
- obj["e" + evType + fn] = null;
78
- }
79
- catch (ex) {
80
- // do nothing;
81
- }
82
- }
83
- }
84
-
85
- function removeEventAttribute(obj, beginName){
86
- var attributes = obj.attributes;
87
- for (var i = 0; i < attributes.length; i++) {
88
- var attribute = attributes[i]
89
- var name = attribute.name
90
- if (name.indexOf(beginName) == 0) {
91
- //obj.removeAttributeNode(attribute);
92
- attribute.specified = false;
93
- }
94
- }
95
- }
96
-
97
- me.addScrollWheelEvent = function(obj, fn){
98
- if (obj.addEventListener) {
99
- /** DOMMouseScroll is for mozilla. */
100
- obj.addEventListener('DOMMouseScroll', fn, true);
101
- }
102
-
103
- /** IE/Opera. */
104
- if (obj.attachEvent) {
105
- obj.attachEvent("onmousewheel", fn);
106
- }
107
-
108
- }
109
-
110
- me.removeScrollWheelEvent = function(obj, fn){
111
- if (obj.removeEventListener) {
112
- /** DOMMouseScroll is for mozilla. */
113
- obj.removeEventListener('DOMMouseScroll', fn, true);
114
- }
115
-
116
- /** IE/Opera. */
117
- if (obj.detachEvent) {
118
- obj.detatchEvent("onmousewheel", fn);
119
- }
120
-
121
- }
122
-
123
- /**
124
- * Given a mouse event, get the mouse pointer's x-coordinate.
125
- *
126
- * @param {Object} e - a DOM Event object.
127
- * @return {int} - the mouse pointer's x-coordinate.
128
- */
129
- me.getMouseX = function(e){
130
- if (!e) {
131
- return;
132
- }
133
- // NS4
134
- if (e.pageX != null) {
135
- return e.pageX;
136
- // IE
137
- } else if (window.event != null && window.event.clientX != null &&
138
- document.body != null &&
139
- document.body.scrollLeft != null)
140
- return window.event.clientX + document.body.scrollLeft;
141
- // W3C
142
- else if (e.clientX != null)
143
- return e.clientX;
144
- else
145
- return null;
146
- }
147
-
148
- /**
149
- * Given a mouse event, get the mouse pointer's y-coordinate.
150
- * @param {Object} e - a DOM Event Object.
151
- * @return {int} - the mouse pointer's y-coordinate.
152
- */
153
- me.getMouseY = function(e){
154
- // NS4
155
- if (e.pageY != null)
156
- return e.pageY;
157
- // IE
158
- else if (window.event != null && window.event.clientY != null &&
159
- document.body != null &&
160
- document.body.scrollTop != null)
161
- return window.event.clientY + document.body.scrollTop;
162
- // W3C
163
- else if (e.clientY != null) {
164
- return e.clientY;
165
- }
166
- }
167
- /**
168
- * Given a mouse scroll wheel event, get the "delta" of how fast it moved.
169
- * @param {Object} e - a DOM Event Object.
170
- * @return {int} - the mouse wheel's delta. It is greater than 0, the
171
- * scroll wheel was spun upwards; if less than 0, downwards.
172
- */
173
- me.getScrollWheelDelta = function(e){
174
- var delta = 0;
175
- if (!e) /* For IE. */
176
- e = window.event;
177
- if (e.wheelDelta) { /* IE/Opera. */
178
- delta = e.wheelDelta / 120;
179
- /** In Opera 9, delta differs in sign as compared to IE.
180
- */
181
- if (window.opera) {
182
- delta = -delta;
183
- }
184
- } else if (e.detail) { /** Mozilla case. */
185
- /** In Mozilla, sign of delta is different than in IE.
186
- * Also, delta is multiple of 3.
187
- */
188
- delta = -e.detail / 3;
189
- }
190
- return delta
191
- }
192
-
193
- /**
194
- * Sets a mouse move event of a document.
195
- *
196
- * @deprecated - use only if compatibility with IE4 and NS4 is necessary. Otherwise, just
197
- * use EventHelpers.addEvent(window, 'mousemove', func) instead. Cannot be used to add
198
- * multiple mouse move event handlers.
199
- *
200
- * @param {Function} func - the function that you want a mouse event to fire.
201
- */
202
- me.addMouseEvent = function(func){
203
-
204
- if (document.captureEvents) {
205
- document.captureEvents(Event.MOUSEMOVE);
206
- }
207
-
208
- document.onmousemove = func;
209
- window.onmousemove = func;
210
- window.onmouseover = func;
211
-
212
- }
213
-
214
-
215
-
216
- /**
217
- * Find the HTML object that fired an Event.
218
- *
219
- * @param {Object} e - an HTML object
220
- * @return {Object} - the HTML object that fired the event.
221
- */
222
- me.getEventTarget = function(e){
223
- // first, IE method for mouse events(also supported by Safari and Opera)
224
- if (e.toElement) {
225
- return e.toElement;
226
- // W3C
227
- } else if (e.currentTarget) {
228
- return e.currentTarget;
229
-
230
- // MS way
231
- } else if (e.srcElement) {
232
- return e.srcElement;
233
- } else {
234
- return null;
235
- }
236
- }
237
-
238
-
239
-
240
-
241
- /**
242
- * Given an event fired by the keyboard, find the key associated with that event.
243
- *
244
- * @param {Object} e - an event object.
245
- * @return {String} - the ASCII character code representing the key associated with the event.
246
- */
247
- me.getKey = function(e){
248
- if (e.keyCode) {
249
- return e.keyCode;
250
- } else if (e.event && e.event.keyCode) {
251
- return window.event.keyCode;
252
- } else if (e.which) {
253
- return e.which;
254
- }
255
- }
256
-
257
-
258
- /**
259
- * Will execute a function when the page's DOM has fully loaded (and before all attached images, iframes,
260
- * etc., are).
261
- *
262
- * Usage:
263
- *
264
- * EventHelpers.addPageLoadEvent('init');
265
- *
266
- * where the function init() has this code at the beginning:
267
- *
268
- * function init() {
269
- *
270
- * if (EventHelpers.hasPageLoadHappened(arguments)) return;
271
- *
272
- * // rest of code
273
- * ....
274
- * }
275
- *
276
- * @author This code is based off of code from http://dean.edwards.name/weblog/2005/09/busted/ by Dean
277
- * Edwards, with a modification by me.
278
- *
279
- * @param {String} funcName - a string containing the function to be called.
280
- */
281
- me.addPageLoadEvent = function(funcName){
282
-
283
- var func = eval(funcName);
284
-
285
- // for Internet Explorer (using conditional comments)
286
- /*@cc_on @*/
287
- /*@if (@_win32)
288
- pageLoadEventArray.push(func);
289
- return;
290
- /*@end @*/
291
- if (isSafari) { // sniff
292
- pageLoadEventArray.push(func);
293
-
294
- if (!safariTimer) {
295
-
296
- safariTimer = setInterval(function(){
297
- if (/loaded|complete/.test(document.readyState)) {
298
- clearInterval(safariTimer);
299
-
300
- /*
301
- * call the onload handler
302
- * func();
303
- */
304
- me.runPageLoadEvents();
305
- return;
306
- }
307
- set = true;
308
- }, 10);
309
- }
310
- /* for Mozilla */
311
- } else if (document.addEventListener) {
312
- var x = document.addEventListener("DOMContentLoaded", func, null);
313
-
314
- /* Others */
315
- } else {
316
- me.addEvent(window, 'load', func);
317
- }
318
- }
319
-
320
- var pageLoadEventArray = new Array();
321
-
322
- me.runPageLoadEvents = function(e){
323
- if (isSafari || e.srcElement.readyState == "complete") {
324
-
325
- for (var i = 0; i < pageLoadEventArray.length; i++) {
326
- pageLoadEventArray[i]();
327
- }
328
- }
329
- }
330
- /**
331
- * Determines if either addPageLoadEvent('funcName') or addEvent(window, 'load', funcName)
332
- * has been executed.
333
- *
334
- * @see addPageLoadEvent
335
- * @param {Function} funcArgs - the arguments of the containing. function
336
- */
337
- me.hasPageLoadHappened = function(funcArgs){
338
- // If the function already been called, return true;
339
- if (funcArgs.callee.done)
340
- return true;
341
-
342
- // flag this function so we don't do the same thing twice
343
- funcArgs.callee.done = true;
344
- }
345
-
346
-
347
-
348
- /**
349
- * Used in an event method/function to indicate that the default behaviour of the event
350
- * should *not* happen.
351
- *
352
- * @param {Object} e - an event object.
353
- * @return {Boolean} - always false
354
- */
355
- me.preventDefault = function(e){
356
-
357
- if (e.preventDefault) {
358
- e.preventDefault();
359
- }
360
-
361
- try {
362
- e.returnValue = false;
363
- }
364
- catch (ex) {
365
- // do nothing
366
- }
367
-
368
- }
369
-
370
- me.cancelBubble = function(e){
371
- if (e.stopPropagation) {
372
- e.stopPropagation();
373
- }
374
-
375
- try {
376
- e.cancelBubble = true;
377
- }
378
- catch (ex) {
379
- // do nothing
380
- }
381
- }
382
-
383
- /*
384
- * Fires an event manually.
385
- * @author Scott Andrew - http://www.scottandrew.com/weblog/articles/cbs-events
386
- * @author John Resig - http://ejohn.org/projects/flexible-javascript-events/ * @param {Object} obj - a javascript object.
387
- * @param {String} evType - an event attached to the object.
388
- * @param {Function} fn - the function that is called when the event fires.
389
- *
390
- */
391
- me.fireEvent = function (element,event, options){
392
-
393
- if(!element) {
394
- return;
395
- }
396
-
397
- if (document.createEventObject){
398
- /*
399
- var stack = DebugHelpers.getStackTrace();
400
- var s = stack.toString();
401
- jslog.debug(s);
402
- if (s.indexOf('fireEvent') >= 0) {
403
- return;
404
- }
405
- */
406
- return element.fireEvent('on' + event, globalEvent)
407
- jslog.debug('ss');
408
-
409
- }
410
- else{
411
- // dispatch for firefox + others
412
- globalEvent.initEvent(event, true, true); // event type,bubbling,cancelable
413
- return !element.dispatchEvent(globalEvent);
414
- }
415
- }
416
-
417
- /* EventHelpers.init () */
418
- function init(){
419
- // Conditional comment alert: Do not remove comments. Leave intact.
420
- // The detection if the page is secure or not is important. If
421
- // this logic is removed, Internet Explorer will give security
422
- // alerts.
423
- /*@cc_on @*/
424
- /*@if (@_win32)
425
-
426
- document.write('<script id="__ie_onload" defer src="' +
427
-
428
- ((location.protocol == 'https:') ? '//0' : 'javascript:void(0)') + '"><\/script>');
429
-
430
- var script = document.getElementById("__ie_onload");
431
-
432
- me.addEvent(script, 'readystatechange', me.runPageLoadEvents);
433
-
434
- /*@end @*/
435
-
436
- }
437
-
438
- init();
439
- }
440
-
441
- EventHelpers.addPageLoadEvent('EventHelpers.init');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/dompdf/www/cssSandpaper/js/cssQuery-p.js DELETED
@@ -1,6 +0,0 @@
1
- /*
2
- cssQuery, version 2.0.2 (2005-08-19)
3
- Copyright: 2004-2005, Dean Edwards (http://dean.edwards.name/)
4
- License: http://creativecommons.org/licenses/LGPL/2.1/
5
- */
6
- eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('7 x=6(){7 1D="2.0.2";7 C=/\\s*,\\s*/;7 x=6(s,A){33{7 m=[];7 u=1z.32.2c&&!A;7 b=(A)?(A.31==22)?A:[A]:[1g];7 1E=18(s).1l(C),i;9(i=0;i<1E.y;i++){s=1y(1E[i]);8(U&&s.Z(0,3).2b("")==" *#"){s=s.Z(2);A=24([],b,s[1])}1A A=b;7 j=0,t,f,a,c="";H(j<s.y){t=s[j++];f=s[j++];c+=t+f;a="";8(s[j]=="("){H(s[j++]!=")")a+=s[j];a=a.Z(0,-1);c+="("+a+")"}A=(u&&V[c])?V[c]:21(A,t,f,a);8(u)V[c]=A}m=m.30(A)}2a x.2d;5 m}2Z(e){x.2d=e;5[]}};x.1Z=6(){5"6 x() {\\n [1D "+1D+"]\\n}"};7 V={};x.2c=L;x.2Y=6(s){8(s){s=1y(s).2b("");2a V[s]}1A V={}};7 29={};7 19=L;x.15=6(n,s){8(19)1i("s="+1U(s));29[n]=12 s()};x.2X=6(c){5 c?1i(c):o};7 D={};7 h={};7 q={P:/\\[([\\w-]+(\\|[\\w-]+)?)\\s*(\\W?=)?\\s*([^\\]]*)\\]/};7 T=[];D[" "]=6(r,f,t,n){7 e,i,j;9(i=0;i<f.y;i++){7 s=X(f[i],t,n);9(j=0;(e=s[j]);j++){8(M(e)&&14(e,n))r.z(e)}}};D["#"]=6(r,f,i){7 e,j;9(j=0;(e=f[j]);j++)8(e.B==i)r.z(e)};D["."]=6(r,f,c){c=12 1t("(^|\\\\s)"+c+"(\\\\s|$)");7 e,i;9(i=0;(e=f[i]);i++)8(c.l(e.1V))r.z(e)};D[":"]=6(r,f,p,a){7 t=h[p],e,i;8(t)9(i=0;(e=f[i]);i++)8(t(e,a))r.z(e)};h["2W"]=6(e){7 d=Q(e);8(d.1C)9(7 i=0;i<d.1C.y;i++){8(d.1C[i]==e)5 K}};h["2V"]=6(e){};7 M=6(e){5(e&&e.1c==1&&e.1f!="!")?e:23};7 16=6(e){H(e&&(e=e.2U)&&!M(e))28;5 e};7 G=6(e){H(e&&(e=e.2T)&&!M(e))28;5 e};7 1r=6(e){5 M(e.27)||G(e.27)};7 1P=6(e){5 M(e.26)||16(e.26)};7 1o=6(e){7 c=[];e=1r(e);H(e){c.z(e);e=G(e)}5 c};7 U=K;7 1h=6(e){7 d=Q(e);5(2S d.25=="2R")?/\\.1J$/i.l(d.2Q):2P(d.25=="2O 2N")};7 Q=6(e){5 e.2M||e.1g};7 X=6(e,t){5(t=="*"&&e.1B)?e.1B:e.X(t)};7 17=6(e,t,n){8(t=="*")5 M(e);8(!14(e,n))5 L;8(!1h(e))t=t.2L();5 e.1f==t};7 14=6(e,n){5!n||(n=="*")||(e.2K==n)};7 1e=6(e){5 e.1G};6 24(r,f,B){7 m,i,j;9(i=0;i<f.y;i++){8(m=f[i].1B.2J(B)){8(m.B==B)r.z(m);1A 8(m.y!=23){9(j=0;j<m.y;j++){8(m[j].B==B)r.z(m[j])}}}}5 r};8(![].z)22.2I.z=6(){9(7 i=0;i<1z.y;i++){o[o.y]=1z[i]}5 o.y};7 N=/\\|/;6 21(A,t,f,a){8(N.l(f)){f=f.1l(N);a=f[0];f=f[1]}7 r=[];8(D[t]){D[t](r,A,f,a)}5 r};7 S=/^[^\\s>+~]/;7 20=/[\\s#.:>+~()@]|[^\\s#.:>+~()@]+/g;6 1y(s){8(S.l(s))s=" "+s;5 s.P(20)||[]};7 W=/\\s*([\\s>+~(),]|^|$)\\s*/g;7 I=/([\\s>+~,]|[^(]\\+|^)([#.:@])/g;7 18=6(s){5 s.O(W,"$1").O(I,"$1*$2")};7 1u={1Z:6(){5"\'"},P:/^(\'[^\']*\')|("[^"]*")$/,l:6(s){5 o.P.l(s)},1S:6(s){5 o.l(s)?s:o+s+o},1Y:6(s){5 o.l(s)?s.Z(1,-1):s}};7 1s=6(t){5 1u.1Y(t)};7 E=/([\\/()[\\]?{}|*+-])/g;6 R(s){5 s.O(E,"\\\\$1")};x.15("1j-2H",6(){D[">"]=6(r,f,t,n){7 e,i,j;9(i=0;i<f.y;i++){7 s=1o(f[i]);9(j=0;(e=s[j]);j++)8(17(e,t,n))r.z(e)}};D["+"]=6(r,f,t,n){9(7 i=0;i<f.y;i++){7 e=G(f[i]);8(e&&17(e,t,n))r.z(e)}};D["@"]=6(r,f,a){7 t=T[a].l;7 e,i;9(i=0;(e=f[i]);i++)8(t(e))r.z(e)};h["2G-10"]=6(e){5!16(e)};h["1x"]=6(e,c){c=12 1t("^"+c,"i");H(e&&!e.13("1x"))e=e.1n;5 e&&c.l(e.13("1x"))};q.1X=/\\\\:/g;q.1w="@";q.J={};q.O=6(m,a,n,c,v){7 k=o.1w+m;8(!T[k]){a=o.1W(a,c||"",v||"");T[k]=a;T.z(a)}5 T[k].B};q.1Q=6(s){s=s.O(o.1X,"|");7 m;H(m=s.P(o.P)){7 r=o.O(m[0],m[1],m[2],m[3],m[4]);s=s.O(o.P,r)}5 s};q.1W=6(p,t,v){7 a={};a.B=o.1w+T.y;a.2F=p;t=o.J[t];t=t?t(o.13(p),1s(v)):L;a.l=12 2E("e","5 "+t);5 a};q.13=6(n){1d(n.2D()){F"B":5"e.B";F"2C":5"e.1V";F"9":5"e.2B";F"1T":8(U){5"1U((e.2A.P(/1T=\\\\1v?([^\\\\s\\\\1v]*)\\\\1v?/)||[])[1]||\'\')"}}5"e.13(\'"+n.O(N,":")+"\')"};q.J[""]=6(a){5 a};q.J["="]=6(a,v){5 a+"=="+1u.1S(v)};q.J["~="]=6(a,v){5"/(^| )"+R(v)+"( |$)/.l("+a+")"};q.J["|="]=6(a,v){5"/^"+R(v)+"(-|$)/.l("+a+")"};7 1R=18;18=6(s){5 1R(q.1Q(s))}});x.15("1j-2z",6(){D["~"]=6(r,f,t,n){7 e,i;9(i=0;(e=f[i]);i++){H(e=G(e)){8(17(e,t,n))r.z(e)}}};h["2y"]=6(e,t){t=12 1t(R(1s(t)));5 t.l(1e(e))};h["2x"]=6(e){5 e==Q(e).1H};h["2w"]=6(e){7 n,i;9(i=0;(n=e.1F[i]);i++){8(M(n)||n.1c==3)5 L}5 K};h["1N-10"]=6(e){5!G(e)};h["2v-10"]=6(e){e=e.1n;5 1r(e)==1P(e)};h["2u"]=6(e,s){7 n=x(s,Q(e));9(7 i=0;i<n.y;i++){8(n[i]==e)5 L}5 K};h["1O-10"]=6(e,a){5 1p(e,a,16)};h["1O-1N-10"]=6(e,a){5 1p(e,a,G)};h["2t"]=6(e){5 e.B==2s.2r.Z(1)};h["1M"]=6(e){5 e.1M};h["2q"]=6(e){5 e.1q===L};h["1q"]=6(e){5 e.1q};h["1L"]=6(e){5 e.1L};q.J["^="]=6(a,v){5"/^"+R(v)+"/.l("+a+")"};q.J["$="]=6(a,v){5"/"+R(v)+"$/.l("+a+")"};q.J["*="]=6(a,v){5"/"+R(v)+"/.l("+a+")"};6 1p(e,a,t){1d(a){F"n":5 K;F"2p":a="2n";1a;F"2o":a="2n+1"}7 1m=1o(e.1n);6 1k(i){7 i=(t==G)?1m.y-i:i-1;5 1m[i]==e};8(!Y(a))5 1k(a);a=a.1l("n");7 m=1K(a[0]);7 s=1K(a[1]);8((Y(m)||m==1)&&s==0)5 K;8(m==0&&!Y(s))5 1k(s);8(Y(s))s=0;7 c=1;H(e=t(e))c++;8(Y(m)||m==1)5(t==G)?(c<=s):(s>=c);5(c%m)==s}});x.15("1j-2m",6(){U=1i("L;/*@2l@8(@\\2k)U=K@2j@*/");8(!U){X=6(e,t,n){5 n?e.2i("*",t):e.X(t)};14=6(e,n){5!n||(n=="*")||(e.2h==n)};1h=1g.1I?6(e){5/1J/i.l(Q(e).1I)}:6(e){5 Q(e).1H.1f!="2g"};1e=6(e){5 e.2f||e.1G||1b(e)};6 1b(e){7 t="",n,i;9(i=0;(n=e.1F[i]);i++){1d(n.1c){F 11:F 1:t+=1b(n);1a;F 3:t+=n.2e;1a}}5 t}}});19=K;5 x}();',62,190,'|||||return|function|var|if|for||||||||pseudoClasses||||test|||this||AttributeSelector|||||||cssQuery|length|push|fr|id||selectors||case|nextElementSibling|while||tests|true|false|thisElement||replace|match|getDocument|regEscape||attributeSelectors|isMSIE|cache||getElementsByTagName|isNaN|slice|child||new|getAttribute|compareNamespace|addModule|previousElementSibling|compareTagName|parseSelector|loaded|break|_0|nodeType|switch|getTextContent|tagName|document|isXML|eval|css|_1|split|ch|parentNode|childElements|nthChild|disabled|firstElementChild|getText|RegExp|Quote|x22|PREFIX|lang|_2|arguments|else|all|links|version|se|childNodes|innerText|documentElement|contentType|xml|parseInt|indeterminate|checked|last|nth|lastElementChild|parse|_3|add|href|String|className|create|NS_IE|remove|toString|ST|select|Array|null|_4|mimeType|lastChild|firstChild|continue|modules|delete|join|caching|error|nodeValue|textContent|HTML|prefix|getElementsByTagNameNS|end|x5fwin32|cc_on|standard||odd|even|enabled|hash|location|target|not|only|empty|root|contains|level3|outerHTML|htmlFor|class|toLowerCase|Function|name|first|level2|prototype|item|scopeName|toUpperCase|ownerDocument|Document|XML|Boolean|URL|unknown|typeof|nextSibling|previousSibling|visited|link|valueOf|clearCache|catch|concat|constructor|callee|try'.split('|'),0,{}))
 
 
 
 
 
 
lib/dompdf/www/cssSandpaper/js/cssSandpaper.js DELETED
@@ -1,2395 +0,0 @@
1
-
2
- /*******************************************************************************
3
- * This notice must be untouched at all times.
4
- *
5
- * CSS Sandpaper: smooths out differences between CSS implementations.
6
- *
7
- * This javascript library contains routines to implement the CSS transform,
8
- * box-shadow and gradient in IE. It also provides a common syntax for other
9
- * browsers that support vendor-specific methods.
10
- *
11
- * Written by: Zoltan Hawryluk. Version 1.0 beta 1 completed on March 8, 2010.
12
- *
13
- * Some routines are based on code from CSS Gradients via Canvas v1.2
14
- * by Weston Ruter <http://weston.ruter.net/projects/css-gradients-via-canvas/>
15
- *
16
- * Requires sylvester.js by James Coglan http://sylvester.jcoglan.com/
17
- *
18
- * cssSandpaper.js v.1.0 beta 1 available at http://www.useragentman.com/
19
- *
20
- * released under the MIT License:
21
- * http://www.opensource.org/licenses/mit-license.php
22
- *
23
- ******************************************************************************/
24
- if (!document.querySelectorAll) {
25
- document.querySelectorAll = cssQuery;
26
- }
27
-
28
- var cssSandpaper = new function(){
29
- var me = this;
30
-
31
- var styleNodes, styleSheets = new Array();
32
-
33
- var ruleSetRe = /[^\{]*{[^\}]*}/g;
34
- var ruleSplitRe = /[\{\}]/g;
35
-
36
- var reGradient = /gradient\([\s\S]*\)/g;
37
- var reHSL = /hsl\([\s\S]*\)/g;
38
-
39
- // This regexp from the article
40
- // http://james.padolsey.com/javascript/javascript-comment-removal-revisted/
41
- var reMultiLineComment = /\/\/.+?(?=\n|\r|$)|\/\*[\s\S]+?\*\//g;
42
-
43
- var reAtRule = /@[^\{\};]*;|@[^\{\};]*\{[^\}]*\}/g;
44
-
45
- var reFunctionSpaces = /\(\s*/g
46
-
47
-
48
- var ruleLists = new Array();
49
- var styleNode;
50
-
51
- var tempObj;
52
- var body;
53
-
54
-
55
- me.init = function(reinit){
56
-
57
- if (EventHelpers.hasPageLoadHappened(arguments) && !reinit) {
58
- return;
59
- }
60
-
61
- body = document.body;
62
-
63
- tempObj = document.createElement('div');
64
-
65
- getStyleSheets();
66
-
67
- indexRules();
68
-
69
-
70
- fixTransforms();
71
- fixBoxShadow();
72
- fixLinearGradients();
73
-
74
- fixBackgrounds();
75
- fixColors();
76
- fixOpacity();
77
- setClasses();
78
- //fixBorderRadius();
79
-
80
- }
81
-
82
- me.setOpacity = function(obj, value){
83
- var property = CSS3Helpers.findProperty(document.body, 'opacity');
84
-
85
- if (property == "filter") {
86
- // IE must have layout, see
87
- // http://jszen.blogspot.com/2005/04/ie6-opacity-filter-caveat.html
88
- // for details.
89
- obj.style.zoom = "100%";
90
-
91
- var filter = CSS3Helpers.addFilter(obj, 'DXImageTransform.Microsoft.Alpha', StringHelpers.sprintf("opacity=%d", ((value) * 100)));
92
-
93
- filter.opacity = value * 100;
94
-
95
-
96
- } else if (obj.style[property] != null) {
97
- obj.style[property] = value;
98
- }
99
- }
100
-
101
-
102
- function fixOpacity(){
103
-
104
- var transformRules = getRuleList('opacity').values;
105
-
106
- for (var i in transformRules) {
107
- var rule = transformRules[i];
108
- var nodes = document.querySelectorAll(rule.selector);
109
-
110
- for (var j = 0; j < nodes.length; j++) {
111
- me.setOpacity(nodes[j], rule.value)
112
- }
113
-
114
- }
115
-
116
- }
117
-
118
-
119
-
120
- me.setTransform = function(obj, transformString){
121
- var property = CSS3Helpers.findProperty(obj, 'transform');
122
-
123
- if (property == "filter") {
124
- var matrix = CSS3Helpers.getTransformationMatrix(transformString);
125
- CSS3Helpers.setMatrixFilter(obj, matrix)
126
- } else if (obj.style[property] != null) {
127
- obj.style[property] = transformString;
128
- }
129
- }
130
-
131
- function fixTransforms(){
132
-
133
- var transformRules = getRuleList('-sand-transform').values;
134
- var property = CSS3Helpers.findProperty(document.body, 'transform');
135
-
136
-
137
- for (var i in transformRules) {
138
- var rule = transformRules[i];
139
- var nodes = document.querySelectorAll(rule.selector);
140
-
141
- for (var j = 0; j < nodes.length; j++) {
142
- me.setTransform(nodes[j], rule.value)
143
- }
144
-
145
- }
146
-
147
- }
148
-
149
- me.setBoxShadow = function(obj, value){
150
- var property = CSS3Helpers.findProperty(obj, 'boxShadow');
151
-
152
- var values = CSS3Helpers.getBoxShadowValues(value);
153
-
154
- if (property == "filter") {
155
- var filter = CSS3Helpers.addFilter(obj, 'DXImageTransform.Microsoft.DropShadow', StringHelpers.sprintf("color=%s,offX=%d,offY=%d", values.color, values.offsetX, values.offsetY));
156
- filter.color = values.color;
157
- filter.offX = values.offsetX;
158
- filter.offY = values.offsetY;
159
-
160
- } else if (obj.style[property] != null) {
161
- obj.style[property] = value;
162
- }
163
- }
164
-
165
- function fixBoxShadow(){
166
-
167
- var transformRules = getRuleList('-sand-box-shadow').values;
168
-
169
- //var matrices = new Array();
170
-
171
-
172
- for (var i in transformRules) {
173
- var rule = transformRules[i];
174
-
175
- var nodes = document.querySelectorAll(rule.selector);
176
-
177
-
178
-
179
- for (var j = 0; j < nodes.length; j++) {
180
- me.setBoxShadow(nodes[j], rule.value)
181
-
182
- }
183
-
184
- }
185
-
186
- }
187
-
188
- function setGradientFilter(node, values){
189
-
190
- if (values.colorStops.length == 2 &&
191
- values.colorStops[0].stop == 0.0 &&
192
- values.colorStops[1].stop == 1.0) {
193
- var startColor = new RGBColor(values.colorStops[0].color);
194
- var endColor = new RGBColor(values.colorStops[1].color);
195
-
196
- startColor = startColor.toHex();
197
- endColor = endColor.toHex();
198
-
199
- var filter = CSS3Helpers.addFilter(node, 'DXImageTransform.Microsoft.Gradient', StringHelpers.sprintf("GradientType = %s, StartColorStr = '%s', EndColorStr = '%s'", values.IEdir, startColor, endColor));
200
-
201
- filter.GradientType = values.IEdir;
202
- filter.StartColorStr = startColor;
203
- filter.EndColorStr = endColor;
204
- node.style.zoom = 1;
205
- }
206
- }
207
-
208
- me.setGradient = function(node, value){
209
-
210
- var support = CSS3Helpers.reportGradientSupport();
211
-
212
- var values = CSS3Helpers.getGradient(value);
213
-
214
- if (values == null) {
215
- return;
216
- }
217
-
218
- if (node.filters) {
219
- setGradientFilter(node, values);
220
- } else if (support == implementation.MOZILLA) {
221
-
222
- node.style.backgroundImage = StringHelpers.sprintf('-moz-gradient( %s, %s, from(%s), to(%s))', values.dirBegin, values.dirEnd, values.colorStops[0].color, values.colorStops[1].color);
223
- } else if (support == implementation.WEBKIT) {
224
- var tmp = StringHelpers.sprintf('-webkit-gradient(%s, %s, %s %s, %s %s)', values.type, values.dirBegin, values.r0 ? values.r0 + ", " : "", values.dirEnd, values.r1 ? values.r1 + ", " : "", listColorStops(values.colorStops));
225
- node.style.backgroundImage = tmp;
226
- } else if (support == implementation.CANVAS_WORKAROUND) {
227
- try {
228
- CSS3Helpers.applyCanvasGradient(node, values);
229
- }
230
- catch (ex) {
231
- // do nothing (for now).
232
- }
233
- }
234
- }
235
-
236
- me.setRGBABackground = function(node, value){
237
-
238
- var support = CSS3Helpers.reportColorSpaceSupport('RGBA', colorType.BACKGROUND);
239
-
240
- switch (support) {
241
- case implementation.NATIVE:
242
- node.style.value = value;
243
- break;
244
- case implementation.FILTER_WORKAROUND:
245
- setGradientFilter(node, {
246
- IEdir: 0,
247
- colorStops: [{
248
- stop: 0.0,
249
- color: value
250
- }, {
251
- stop: 1.0,
252
- color: value
253
- }]
254
- });
255
-
256
- break;
257
- }
258
-
259
- }
260
-
261
- me.setHSLABackground = function(node, value) {
262
- var support = CSS3Helpers.reportColorSpaceSupport('HSLA', colorType.BACKGROUND);
263
-
264
- switch (support) {
265
- case implementation.NATIVE:
266
- /* node.style.value = value;
267
- break; */
268
- case implementation.FILTER_WORKAROUND:
269
- var rgbColor = new RGBColor(value);
270
-
271
- if (rgbColor.a == 1) {
272
- node.style.backgroundColor = rgbColor.toHex();
273
- } else {
274
- var rgba = rgbColor.toRGBA();
275
- setGradientFilter(node, {
276
- IEdir: 0,
277
- colorStops: [{
278
- stop: 0.0,
279
- color: rgba
280
- }, {
281
- stop: 1.0,
282
- color: rgba
283
- }]
284
- });
285
- }
286
- break;
287
- }
288
- }
289
-
290
- /**
291
- * Convert a hyphenated string to camelized text. For example, the string "font-type" will be converted
292
- * to "fontType".
293
- *
294
- * @param {Object} s - the string that needs to be camelized.
295
- * @return {String} - the camelized text.
296
- */
297
- me.camelize = function (s) {
298
- var r="";
299
-
300
- for (var i=0; i<s.length; i++) {
301
- if (s.substring(i, i+1) == '-') {
302
- i++;
303
- r+= s.substring(i, i+1).toUpperCase();
304
- } else {
305
- r+= s.substring(i, i+1);
306
- }
307
- }
308
-
309
- return r;
310
- }
311
-
312
- me.setHSLColor = function (node, property, value) {
313
- var support = CSS3Helpers.reportColorSpaceSupport('HSL', colorType.FOREGROUND);
314
-
315
- switch (support) {
316
- case implementation.NATIVE:
317
- /* node.style.value = value;
318
- break; */
319
- case implementation.HEX_WORKAROUND:
320
-
321
- var hslColor = value.match(reHSL)[0];
322
- var hexColor = new RGBColor(hslColor).toHex()
323
- var newPropertyValue = value.replace(reHSL, hexColor);
324
-
325
-
326
-
327
- node.style[me.camelize(property)] = newPropertyValue;
328
-
329
- break;
330
- }
331
-
332
- }
333
-
334
-
335
- function fixLinearGradients(){
336
-
337
- var backgroundRules = getRuleList('background').values.concat(getRuleList('background-image').values);
338
-
339
- for (var i in backgroundRules) {
340
- var rule = backgroundRules[i];
341
- var nodes = document.querySelectorAll(rule.selector);
342
- for (var j = 0; j < nodes.length; j++) {
343
- me.setGradient(nodes[j], rule.value)
344
- }
345
- }
346
- }
347
-
348
- function fixBackgrounds(){
349
-
350
- var support = CSS3Helpers.reportColorSpaceSupport('RGBA', colorType.BACKGROUND);
351
- if (support == implementation.NATIVE) {
352
- return;
353
- }
354
-
355
-
356
- var backgroundRules = getRuleList('background').values.concat(getRuleList('background-color').values);
357
-
358
- for (var i in backgroundRules) {
359
- var rule = backgroundRules[i];
360
- var nodes = document.querySelectorAll(rule.selector);
361
- for (var j = 0; j < nodes.length; j++) {
362
- if (rule.value.indexOf('rgba(') == 0) {
363
- me.setRGBABackground(nodes[j], rule.value);
364
- } else if (rule.value.indexOf('hsla(') == 0 || rule.value.indexOf('hsl(') == 0) {
365
-
366
- me.setHSLABackground(nodes[j], rule.value);
367
- }
368
- }
369
- }
370
- }
371
-
372
- me.getProperties = function (obj, objName)
373
- {
374
- var result = ""
375
-
376
- if (!obj) {
377
- return result;
378
- }
379
-
380
- for (var i in obj)
381
- {
382
- try {
383
- result += objName + "." + i.toString() + " = " + obj[i] + ", ";
384
- } catch (ex) {
385
- // nothing
386
- }
387
- }
388
- return result
389
- }
390
-
391
- function fixColors() {
392
- var support = CSS3Helpers.reportColorSpaceSupport('HSL', colorType.FOREGROUND);
393
- if (support == implementation.NATIVE) {
394
- return;
395
- }
396
-
397
- var colorRules = getRuleList('color').values;
398
-
399
- var properties = ['color', 'border',
400
- 'border-left', 'border-right', 'border-bottom', 'border-top',
401
- 'border-left-color', 'border-right-color', 'border-bottom-color', 'border-top-color'];
402
-
403
- for (var i=0; i<properties.length; i++) {
404
- var rules = getRuleList(properties[i]).values;
405
- colorRules = colorRules.concat(rules);
406
- }
407
-
408
- for (var i in colorRules) {
409
- var rule = colorRules[i];
410
-
411
- var nodes = document.querySelectorAll(rule.selector);
412
- for (var j = 0; j < nodes.length; j++) {
413
- var isBorder = (rule.name.indexOf('border') == 0);
414
- var ruleMatch = rule.value.match(reHSL);
415
-
416
-
417
- if (ruleMatch) {
418
-
419
- var cssProperty;
420
- if (isBorder && rule.name.indexOf('-color') < 0) {
421
- cssProperty = rule.name;
422
- } else {
423
- cssProperty = rule.name;
424
- }
425
-
426
- me.setHSLColor(nodes[j], cssProperty, rule.value);
427
-
428
- }
429
- }
430
- }
431
- }
432
-
433
-
434
-
435
- function listColorStops(colorStops){
436
- var sb = new StringBuffer();
437
-
438
- for (var i = 0; i < colorStops.length; i++) {
439
- sb.append(StringHelpers.sprintf("color-stop(%s, %s)", colorStops[i].stop, colorStops[i].color));
440
- if (i < colorStops.length - 1) {
441
- sb.append(', ');
442
- }
443
- }
444
-
445
- return sb.toString();
446
- }
447
-
448
-
449
- function getStyleSheet(node){
450
- var sheetCssText;
451
- switch (node.nodeName.toLowerCase()) {
452
- case 'style':
453
- sheetCssText = StringHelpers.uncommentHTML(node.innerHTML); //does not work with inline styles because IE doesn't allow you to get the text content of a STYLE element
454
- break;
455
- case 'link':
456
-
457
- var xhr = XMLHelpers.getXMLHttpRequest(node.href, null, "GET", null, false);
458
- sheetCssText = xhr.responseText;
459
-
460
- break;
461
- }
462
-
463
- sheetCssText = sheetCssText.replace(reMultiLineComment, '').replace(reAtRule, '');
464
-
465
- return sheetCssText;
466
- }
467
-
468
- function getStyleSheets(){
469
-
470
- styleNodes = document.querySelectorAll('style, link[rel="stylesheet"]');
471
-
472
- for (var i = 0; i < styleNodes.length; i++) {
473
- if (!CSSHelpers.isMemberOfClass(styleNodes[i], 'cssSandpaper-noIndex')) {
474
- styleSheets.push(getStyleSheet(styleNodes[i]))
475
- }
476
- }
477
- }
478
-
479
- function indexRules(){
480
-
481
- for (var i = 0; i < styleSheets.length; i++) {
482
- var sheet = styleSheets[i];
483
-
484
- rules = sheet.match(ruleSetRe);
485
- if (rules) {
486
- for (var j = 0; j < rules.length; j++) {
487
- var parsedRule = rules[j].split(ruleSplitRe);
488
- var selector = parsedRule[0].trim();
489
- var propertiesStr = parsedRule[1];
490
- var properties = propertiesStr.split(';');
491
- for (var k = 0; k < properties.length; k++) {
492
- if (properties[k].trim() != '') {
493
- var splitProperty = properties[k].split(':')
494
- var name = splitProperty[0].trim().toLowerCase();
495
- var value = splitProperty[1];
496
- if (!ruleLists[name]) {
497
- ruleLists[name] = new RuleList(name);
498
- }
499
-
500
- if (value && typeof(ruleLists[name]) == 'object') {
501
- ruleLists[name].add(selector, value.trim());
502
- }
503
- }
504
- }
505
- }
506
- }
507
- }
508
-
509
- }
510
-
511
- function getRuleList(name){
512
- var list = ruleLists[name];
513
- if (!list) {
514
- list = new RuleList(name);
515
- }
516
- return list;
517
- }
518
-
519
- function setClasses(){
520
-
521
-
522
- var htmlNode = document.getElementsByTagName('html')[0];
523
- var properties = ['transform', 'opacity'];
524
-
525
- for (var i = 0; i < properties.length; i++) {
526
- var prop = properties[i];
527
- if (CSS3Helpers.supports(prop)) {
528
- CSSHelpers.addClass(htmlNode, 'cssSandpaper-' + prop);
529
- }
530
- }
531
-
532
- // Now .. remove the initially hidden classes
533
- var hiddenNodes = CSSHelpers.getElementsByClassName(document, 'cssSandpaper-initiallyHidden');
534
-
535
- for (var i=0; i<hiddenNodes.length; i++){
536
- CSSHelpers.removeClass(hiddenNodes[i], 'cssSandpaper-initiallyHidden');
537
- }
538
- }
539
- }
540
-
541
- function RuleList(propertyName){
542
- var me = this;
543
- me.values = new Array();
544
- me.propertyName = propertyName;
545
- me.add = function(selector, value){
546
- me.values.push(new CSSRule(selector, me.propertyName, value));
547
- }
548
- }
549
-
550
- function CSSRule(selector, name, value){
551
- var me = this;
552
- me.selector = selector;
553
- me.name = name;
554
- me.value = value;
555
-
556
- me.toString = function(){
557
- return StringHelpers.sprintf("%s { %s: %s}", me.selector, me.name, me.value);
558
- }
559
- }
560
-
561
- var MatrixGenerator = new function(){
562
- var me = this;
563
- var reUnit = /[a-z]+$/;
564
- me.identity = $M([[1, 0, 0], [0, 1, 0], [0, 0, 1]]);
565
-
566
-
567
- function degreesToRadians(degrees){
568
- return (degrees - 360) * Math.PI / 180;
569
- }
570
-
571
- function getRadianScalar(angleStr){
572
-
573
- var num = parseFloat(angleStr);
574
- var unit = angleStr.match(reUnit);
575
-
576
-
577
- if (angleStr.trim() == '0') {
578
- num = 0;
579
- unit = 'rad';
580
- }
581
-
582
- if (unit.length != 1 || num == 0) {
583
- return 0;
584
- }
585
-
586
-
587
- unit = unit[0];
588
-
589
-
590
- var rad;
591
- switch (unit) {
592
- case "deg":
593
- rad = degreesToRadians(num);
594
- break;
595
- case "rad":
596
- rad = num;
597
- break;
598
- default:
599
- throw "Not an angle: " + angleStr;
600
- }
601
- return rad;
602
- }
603
-
604
- me.prettyPrint = function(m){
605
- return StringHelpers.sprintf('| %s %s %s | - | %s %s %s | - |%s %s %s|', m.e(1, 1), m.e(1, 2), m.e(1, 3), m.e(2, 1), m.e(2, 2), m.e(2, 3), m.e(3, 1), m.e(3, 2), m.e(3, 3))
606
- }
607
-
608
- me.rotate = function(angleStr){
609
- var num = getRadianScalar(angleStr);
610
- return Matrix.RotationZ(num);
611
- }
612
-
613
- me.scale = function(sx, sy){
614
- sx = parseFloat(sx)
615
-
616
- if (!sy) {
617
- sy = sx;
618
- } else {
619
- sy = parseFloat(sy)
620
- }
621
-
622
-
623
- return $M([[sx, 0, 0], [0, sy, 0], [0, 0, 1]]);
624
- }
625
-
626
- me.scaleX = function(sx){
627
- return me.scale(sx, 1);
628
- }
629
-
630
- me.scaleY = function(sy){
631
- return me.scale(1, sy);
632
- }
633
-
634
- me.skew = function(ax, ay){
635
- var xRad = getRadianScalar(ax);
636
- var yRad;
637
-
638
- if (ay != null) {
639
- yRad = getRadianScalar(ay)
640
- } else {
641
- yRad = xRad
642
- }
643
-
644
- if (xRad != null && yRad != null) {
645
-
646
- return $M([[1, Math.tan(xRad), 0], [Math.tan(yRad), 1, 0], [0, 0, 1]]);
647
- } else {
648
- return null;
649
- }
650
- }
651
-
652
- me.skewX = function(ax){
653
-
654
- return me.skew(ax, "0");
655
- }
656
-
657
- me.skewY = function(ay){
658
- return me.skew("0", ay);
659
- }
660
-
661
- me.translate = function(tx, ty){
662
-
663
- var TX = parseInt(tx);
664
- var TY = parseInt(ty)
665
-
666
- //jslog.debug(StringHelpers.sprintf('translate %f %f', TX, TY));
667
-
668
- return $M([[1, 0, TX], [0, 1, TY], [0, 0, 1]]);
669
- }
670
-
671
- me.translateX = function(tx){
672
- return me.translate(tx, 0);
673
- }
674
-
675
- me.translateY = function(ty){
676
- return me.translate(0, ty);
677
- }
678
-
679
-
680
- me.matrix = function(a, b, c, d, e, f){
681
-
682
- // for now, e and f are ignored
683
- return $M([[a, c, parseInt(e)], [b, d, parseInt(f)], [0, 0, 1]])
684
- }
685
- }
686
-
687
- var CSS3Helpers = new function(){
688
- var me = this;
689
-
690
-
691
- var reTransformListSplitter = /[a-zA-Z]+\([^\)]*\)\s*/g;
692
-
693
- var reLeftBracket = /\(/g;
694
- var reRightBracket = /\)/g;
695
- var reComma = /,/g;
696
-
697
- var reSpaces = /\s+/g
698
-
699
- var reFilterNameSplitter = /progid:([^\(]*)/g;
700
-
701
- var reLinearGradient
702
-
703
- var canvas;
704
-
705
- var cache = new Array();
706
-
707
-
708
- me.supports = function(cssProperty){
709
- if (CSS3Helpers.findProperty(document.body, cssProperty) != null) {
710
- return true;
711
- } else {
712
- return false;
713
- }
714
- }
715
-
716
- me.getCanvas = function(){
717
-
718
- if (canvas) {
719
- return canvas;
720
- } else {
721
- canvas = document.createElement('canvas');
722
- return canvas;
723
- }
724
- }
725
-
726
- me.getTransformationMatrix = function(CSS3TransformProperty, doThrowIfError){
727
-
728
- var transforms = CSS3TransformProperty.match(reTransformListSplitter);
729
-
730
- /*
731
- * Do a check here to see if there is anything in the transformation
732
- * besides legit transforms
733
- */
734
- if (doThrowIfError) {
735
- var checkString = transforms.join(" ").replace(/\s*/g, ' ');
736
- var normalizedCSSProp = CSS3TransformProperty.replace(/\s*/g, ' ');
737
-
738
- if (checkString != normalizedCSSProp) {
739
- throw ("An invalid transform was given.")
740
- }
741
- }
742
-
743
-
744
- var resultantMatrix = MatrixGenerator.identity;
745
-
746
- for (var j = 0; j < transforms.length; j++) {
747
-
748
- var transform = transforms[j];
749
-
750
- transform = transform.replace(reLeftBracket, '("').replace(reComma, '", "').replace(reRightBracket, '")');
751
-
752
-
753
- try {
754
- var matrix = eval('MatrixGenerator.' + transform);
755
-
756
-
757
- //jslog.debug( transform + ': ' + MatrixGenerator.prettyPrint(matrix))
758
- resultantMatrix = resultantMatrix.x(matrix);
759
- }
760
- catch (ex) {
761
-
762
- if (doThrowIfError) {
763
- var method = transform.split('(')[0];
764
-
765
- var funcCall = transform.replace(/\"/g, '');
766
-
767
- if (MatrixGenerator[method] == undefined) {
768
- throw "Error: invalid tranform function: " + funcCall;
769
- } else {
770
- throw "Error: Invalid or missing parameters in function call: " + funcCall;
771
-
772
- }
773
- }
774
- // do nothing;
775
- }
776
- }
777
-
778
- return resultantMatrix;
779
-
780
- }
781
-
782
- me.getBoxShadowValues = function(propertyValue){
783
- var r = new Object();
784
-
785
- var values = propertyValue.split(reSpaces);
786
-
787
- if (values[0] == 'inset') {
788
- r.inset = true;
789
- values = values.reverse().pop().reverse();
790
- } else {
791
- r.inset = false;
792
- }
793
-
794
- r.offsetX = parseInt(values[0]);
795
- r.offsetY = parseInt(values[1]);
796
-
797
- if (values.length > 3) {
798
- r.blurRadius = values[2];
799
-
800
- if (values.length > 4) {
801
- r.spreadRadius = values[3]
802
- }
803
- }
804
-
805
- r.color = values[values.length - 1];
806
-
807
- return r;
808
- }
809
-
810
- me.getGradient = function(propertyValue){
811
- var r = new Object();
812
- r.colorStops = new Array();
813
-
814
-
815
- var substring = me.getBracketedSubstring(propertyValue, '-sand-gradient');
816
- if (substring == undefined) {
817
- return null;
818
- }
819
- var parameters = substring.match(/[^\(,]+(\([^\)]*\))?[^,]*/g); //substring.split(reComma);
820
- r.type = parameters[0].trim();
821
-
822
- if (r.type == 'linear') {
823
- r.dirBegin = parameters[1].trim();
824
- r.dirEnd = parameters[2].trim();
825
- var beginCoord = r.dirBegin.split(reSpaces);
826
- var endCoord = r.dirEnd.split(reSpaces);
827
-
828
- for (var i = 3; i < parameters.length; i++) {
829
- r.colorStops.push(parseColorStop(parameters[i].trim(), i - 3));
830
- }
831
-
832
-
833
-
834
-
835
- /* The following logic only applies to IE */
836
- if (document.body.filters) {
837
- if (r.x0 == r.x1) {
838
- /* IE only supports "center top", "center bottom", "top left" and "top right" */
839
-
840
- switch (beginCoord[1]) {
841
- case 'top':
842
- r.IEdir = 0;
843
- break;
844
- case 'bottom':
845
- swapIndices(r.colorStops, 0, 1);
846
- r.IEdir = 0;
847
- /* r.from = parameters[4].trim();
848
- r.to = parameters[3].trim(); */
849
- break;
850
- }
851
- }
852
-
853
- if (r.y0 == r.y1) {
854
- switch (beginCoord[0]) {
855
- case 'left':
856
- r.IEdir = 1;
857
- break;
858
- case 'right':
859
- r.IEdir = 1;
860
- swapIndices(r.colorStops, 0, 1);
861
-
862
- break;
863
- }
864
- }
865
- }
866
- } else {
867
-
868
- // don't even bother with IE
869
- if (document.body.filters) {
870
- return null;
871
- }
872
-
873
-
874
- r.dirBegin = parameters[1].trim();
875
- r.r0 = parameters[2].trim();
876
-
877
- r.dirEnd = parameters[3].trim();
878
- r.r1 = parameters[4].trim();
879
-
880
- var beginCoord = r.dirBegin.split(reSpaces);
881
- var endCoord = r.dirEnd.split(reSpaces);
882
-
883
- for (var i = 5; i < parameters.length; i++) {
884
- r.colorStops.push(parseColorStop(parameters[i].trim(), i - 5));
885
- }
886
-
887
- }
888
-
889
-
890
- r.x0 = beginCoord[0];
891
- r.y0 = beginCoord[1];
892
-
893
- r.x1 = endCoord[0];
894
- r.y1 = endCoord[1];
895
-
896
- return r;
897
- }
898
-
899
- function swapIndices(array, index1, index2){
900
- var tmp = array[index1];
901
- array[index1] = array[index2];
902
- array[index2] = tmp;
903
- }
904
-
905
- function parseColorStop(colorStop, index){
906
- var r = new Object();
907
- var substring = me.getBracketedSubstring(colorStop, 'color-stop');
908
- var from = me.getBracketedSubstring(colorStop, 'from');
909
- var to = me.getBracketedSubstring(colorStop, 'to');
910
-
911
-
912
- if (substring) {
913
- //color-stop
914
- var parameters = substring.split(',')
915
- r.stop = normalizePercentage(parameters[0].trim());
916
- r.color = parameters[1].trim();
917
- } else if (from) {
918
- r.stop = 0.0;
919
- r.color = from.trim();
920
- } else if (to) {
921
- r.stop = 1.0;
922
- r.color = to.trim();
923
- } else {
924
- if (index <= 1) {
925
- r.color = colorStop;
926
- if (index == 0) {
927
- r.stop = 0.0;
928
- } else {
929
- r.stop = 1.0;
930
- }
931
- } else {
932
- throw (StringHelpers.sprintf('invalid argument "%s"', colorStop));
933
- }
934
- }
935
- return r;
936
- }
937
-
938
- function normalizePercentage(s){
939
- if (s.substring(s.length - 1, s.length) == '%') {
940
- return parseFloat(s) / 100 + "";
941
- } else {
942
- return s;
943
- }
944
-
945
- }
946
-
947
- me.reportGradientSupport = function(){
948
-
949
- if (!cache["gradientSupport"]) {
950
- var r;
951
- var div = document.createElement('div');
952
- div.style.cssText = "background-image:-webkit-gradient(linear, 0% 0%, 0% 100%, from(red), to(blue));";
953
-
954
- if (div.style.backgroundImage) {
955
- r = implementation.WEBKIT;
956
-
957
- } else {
958
-
959
- /* div.style.cssText = "background-image:-moz-linear-gradient(top, blue, white 80%, orange);";
960
-
961
- if (div.style.backgroundImage) {
962
-
963
- r = implementation.MOZILLA;
964
-
965
- } else { */
966
- var canvas = CSS3Helpers.getCanvas();
967
- if (canvas.getContext && canvas.toDataURL) {
968
- r = implementation.CANVAS_WORKAROUND;
969
-
970
- } else {
971
- r = implementation.NONE;
972
- }
973
- /* } */
974
- }
975
-
976
- cache["gradientSupport"] = r;
977
- }
978
- return cache["gradientSupport"];
979
- }
980
-
981
- me.reportColorSpaceSupport = function(colorSpace, type){
982
-
983
- if (!cache[colorSpace + type]) {
984
- var r;
985
- var div = document.createElement('div');
986
-
987
- switch (type) {
988
-
989
- case colorType.BACKGROUND:
990
-
991
- switch(colorSpace) {
992
- case 'RGBA':
993
- div.style.cssText = "background-color: rgba(255, 32, 34, 0.5)";
994
- break;
995
- case 'HSL':
996
- div.style.cssText = "background-color: hsl(0,0%,100%)";
997
- break;
998
- case 'HSLA':
999
- div.style.cssText = "background-color: hsla(0,0%,100%,.5)";
1000
- break;
1001
-
1002
- default:
1003
- break;
1004
- }
1005
-
1006
-
1007
-
1008
- var body = document.body;
1009
-
1010
-
1011
- if (div.style.backgroundColor) {
1012
- r = implementation.NATIVE;
1013
-
1014
- } else if (body.filters && body.filters != undefined) {
1015
- r = implementation.FILTER_WORKAROUND;
1016
- } else {
1017
- r = implementation.NONE;
1018
- }
1019
- break;
1020
- case colorType.FOREGROUND:
1021
- switch(colorSpace) {
1022
- case 'RGBA':
1023
- div.style.cssText = "color: rgba(255, 32, 34, 0.5)";
1024
- break;
1025
- case 'HSL':
1026
- div.style.cssText = "color: hsl(0,0%,100%)";
1027
- break;
1028
- case 'HSLA':
1029
- div.style.cssText = "color: hsla(0,0%,100%,.5)";
1030
- break;
1031
-
1032
- default:
1033
- break;
1034
- }
1035
-
1036
- if (div.style.color) {
1037
- r = implementation.NATIVE;
1038
- } else if (colorSpace == 'HSL') {
1039
-
1040
- r = implementation.HEX_WORKAROUND;
1041
- } else {
1042
- r = implementation.NONE;
1043
- }
1044
- break
1045
- }
1046
-
1047
-
1048
- cache[colorSpace] = r;
1049
- }
1050
- return cache[colorSpace];
1051
- }
1052
-
1053
-
1054
-
1055
- me.getBracketedSubstring = function(s, header){
1056
- var gradientIndex = s.indexOf(header + '(')
1057
-
1058
- if (gradientIndex != -1) {
1059
- var substring = s.substring(gradientIndex);
1060
-
1061
- var openBrackets = 1;
1062
- for (var i = header.length + 1; i < 100 || i < substring.length; i++) {
1063
- var c = substring.substring(i, i + 1);
1064
- switch (c) {
1065
- case "(":
1066
- openBrackets++;
1067
- break;
1068
- case ")":
1069
- openBrackets--;
1070
- break;
1071
- }
1072
-
1073
- if (openBrackets == 0) {
1074
- break;
1075
- }
1076
-
1077
- }
1078
-
1079
- return substring.substring(gradientIndex + header.length + 1, i);
1080
- }
1081
-
1082
-
1083
- }
1084
-
1085
-
1086
- me.setMatrixFilter = function(obj, matrix){
1087
-
1088
-
1089
- if (!hasIETransformWorkaround(obj)) {
1090
- addIETransformWorkaround(obj)
1091
- }
1092
-
1093
- var container = obj.parentNode;
1094
- //container.xTransform = degrees;
1095
-
1096
-
1097
- filter = obj.filters.item('DXImageTransform.Microsoft.Matrix');
1098
- //jslog.debug(MatrixGenerator.prettyPrint(matrix))
1099
- filter.M11 = matrix.e(1, 1);
1100
- filter.M12 = matrix.e(1, 2);
1101
- filter.M21 = matrix.e(2, 1);
1102
- filter.M22 = matrix.e(2, 2);
1103
-
1104
-
1105
- // Now, adjust the margins of the parent object
1106
- var offsets = me.getIEMatrixOffsets(obj, matrix, container.xOriginalWidth, container.xOriginalHeight);
1107
- container.style.marginLeft = offsets.x;
1108
- container.style.marginTop = offsets.y;
1109
- container.style.marginRight = 0;
1110
- container.style.marginBottom = 0;
1111
- }
1112
-
1113
- me.getTransformedDimensions = function (obj, matrix) {
1114
- var r = {};
1115
-
1116
- if (hasIETransformWorkaround(obj)) {
1117
- r.width = obj.offsetWidth;
1118
- r.height = obj.offsetHeight;
1119
- } else {
1120
- var pts = [
1121
- matrix.x($V([0, 0, 1])) ,
1122
- matrix.x($V([0, obj.offsetHeight, 1])),
1123
- matrix.x($V([obj.offsetWidth, 0, 1])),
1124
- matrix.x($V([obj.offsetWidth, obj.offsetHeight, 1]))
1125
- ];
1126
- var maxX = 0, maxY =0, minX=0, minY=0;
1127
-
1128
- for (var i = 0; i < pts.length; i++) {
1129
- var pt = pts[i];
1130
- var x = pt.e(1), y = pt.e(2);
1131
- var minX = Math.min(minX, x);
1132
- var maxX = Math.max(maxX, x);
1133
- var minY = Math.min(minY, y);
1134
- var maxY = Math.max(maxY, y);
1135
- }
1136
-
1137
-
1138
- r.width = maxX - minX;
1139
- r.height = maxY - minY;
1140
-
1141
- }
1142
-
1143
- return r;
1144
- }
1145
-
1146
- me.getIEMatrixOffsets = function (obj, matrix, width, height) {
1147
- var r = {};
1148
-
1149
- var originalWidth = parseFloat(width);
1150
- var originalHeight = parseFloat(height);
1151
-
1152
-
1153
- var offset;
1154
- if (CSSHelpers.getComputedStyle(obj, 'display') == 'inline') {
1155
- offset = 0;
1156
- } else {
1157
- offset = 13; // This works ... don't know why.
1158
- }
1159
- var transformedDimensions = me.getTransformedDimensions(obj, matrix);
1160
-
1161
- r.x = (((originalWidth - transformedDimensions.width) / 2) - offset + matrix.e(1, 3)) + 'px';
1162
- r.y = (((originalHeight - transformedDimensions.height) / 2) - offset + matrix.e(2, 3)) + 'px';
1163
-
1164
- return r;
1165
- }
1166
-
1167
- function hasIETransformWorkaround(obj){
1168
-
1169
- return CSSHelpers.isMemberOfClass(obj.parentNode, 'IETransformContainer');
1170
- }
1171
-
1172
- function addIETransformWorkaround(obj){
1173
- if (!hasIETransformWorkaround(obj)) {
1174
- var parentNode = obj.parentNode;
1175
- var filter;
1176
-
1177
- // This is the container to offset the strange rotation behavior
1178
- var container = document.createElement('div');
1179
- CSSHelpers.addClass(container, 'IETransformContainer');
1180
-
1181
-
1182
- container.style.width = obj.offsetWidth + 'px';
1183
- container.style.height = obj.offsetHeight + 'px';
1184
-
1185
- container.xOriginalWidth = obj.offsetWidth;
1186
- container.xOriginalHeight = obj.offsetHeight;
1187
- container.style.position = 'absolute'
1188
- container.style.zIndex = obj.currentStyle.zIndex;
1189
-
1190
-
1191
- var horizPaddingFactor = 0; //parseInt(obj.currentStyle.paddingLeft);
1192
- var vertPaddingFactor = 0; //parseInt(obj.currentStyle.paddingTop);
1193
- if (obj.currentStyle.display == 'block') {
1194
- container.style.left = obj.offsetLeft + 13 - horizPaddingFactor + "px";
1195
- container.style.top = obj.offsetTop + 13 + -vertPaddingFactor + 'px';
1196
- } else {
1197
- container.style.left = obj.offsetLeft + "px";
1198
- container.style.top = obj.offsetTop + 'px';
1199
-
1200
- }
1201
- //container.style.float = obj.currentStyle.float;
1202
-
1203
-
1204
- obj.style.top = "auto";
1205
- obj.style.left = "auto"
1206
- obj.style.bottom = "auto";
1207
- obj.style.right = "auto";
1208
- // This is what we need in order to insert to keep the document
1209
- // flow ok
1210
- var replacement = obj.cloneNode(true);
1211
- replacement.style.visibility = 'hidden';
1212
-
1213
- obj.replaceNode(replacement);
1214
-
1215
- // now, wrap container around the original node ...
1216
-
1217
- obj.style.position = 'absolute';
1218
- container.appendChild(obj);
1219
- parentNode.insertBefore(container, replacement);
1220
- container.style.backgroundColor = 'transparent';
1221
-
1222
- container.style.padding = '0';
1223
-
1224
- filter = me.addFilter(obj, 'DXImageTransform.Microsoft.Matrix', "M11=1, M12=0, M21=0, M22=1, sizingMethod='auto expand'")
1225
- var bgImage = obj.currentStyle.backgroundImage.split("\"")[1];
1226
- /*
1227
-
1228
-
1229
-
1230
- if (bgImage) {
1231
-
1232
-
1233
-
1234
- var alphaFilter = me.addFilter(obj, "DXImageTransform.Microsoft.AlphaImageLoader", "src='" + bgImage + "', sizingMethod='scale'");
1235
-
1236
-
1237
-
1238
- alert(bgImage)
1239
-
1240
-
1241
-
1242
- alphaFilter.src = bgImage;
1243
-
1244
-
1245
-
1246
- sizingMethod = 'scale';
1247
-
1248
-
1249
-
1250
- obj.style.background = 'none';
1251
-
1252
-
1253
-
1254
- obj.style.backgroundImage = 'none';
1255
-
1256
-
1257
-
1258
- }
1259
-
1260
-
1261
-
1262
- */
1263
-
1264
- }
1265
-
1266
- }
1267
-
1268
- me.addFilter = function(obj, filterName, filterValue){
1269
- // now ... insert the filter so we can exploit its wonders
1270
-
1271
- var filter;
1272
- try {
1273
- filter = obj.filters.item(filterName);
1274
- }
1275
- catch (ex) {
1276
- // dang! We have to go through all of them and make sure filter
1277
- // is set right before we add the new one.
1278
-
1279
-
1280
- var filterList = new MSFilterList(obj)
1281
-
1282
- filterList.fixFilterStyle();
1283
-
1284
- var comma = ", ";
1285
-
1286
- if (obj.filters.length == 0) {
1287
- comma = "";
1288
- }
1289
-
1290
- obj.style.filter += StringHelpers.sprintf("%sprogid:%s(%s)", comma, filterName, filterValue);
1291
-
1292
- filter = obj.filters.item(filterName);
1293
-
1294
- }
1295
-
1296
- return filter;
1297
- }
1298
-
1299
-
1300
- function degreesToRadians(degrees){
1301
- return (degrees - 360) * Math.PI / 180;
1302
- }
1303
-
1304
- me.findProperty = function(obj, type){
1305
- capType = type.capitalize();
1306
-
1307
- var r = cache[type]
1308
- if (!r) {
1309
-
1310
-
1311
- var style = obj.style;
1312
-
1313
-
1314
- var properties = [type, 'Moz' + capType, 'Webkit' + capType, 'O' + capType, 'filter'];
1315
- for (var i = 0; i < properties.length; i++) {
1316
- if (style[properties[i]] != null) {
1317
- r = properties[i];
1318
- break;
1319
- }
1320
- }
1321
-
1322
- if (r == 'filter' && document.body.filters == undefined) {
1323
- r = null;
1324
- }
1325
- cache[type] = r;
1326
- }
1327
- return r;
1328
- }
1329
-
1330
- /*
1331
- * "A point is a pair of space-separated values. The syntax supports numbers,
1332
- * percentages or the keywords top, bottom, left and right for point values."
1333
- * This keywords and percentages into pixel equivalents
1334
- */
1335
- me.parseCoordinate = function(value, max){
1336
- //Convert keywords
1337
- switch (value) {
1338
- case 'top':
1339
- case 'left':
1340
- return 0;
1341
- case 'bottom':
1342
- case 'right':
1343
- return max;
1344
- case 'center':
1345
- return max / 2;
1346
- }
1347
-
1348
- //Convert percentage
1349
- if (value.indexOf('%') != -1)
1350
- value = parseFloat(value.substr(0, value.length - 1)) / 100 * max;
1351
- //Convert bare number (a pixel value)
1352
- else
1353
- value = parseFloat(value);
1354
- if (isNaN(value))
1355
- throw Error("Unable to parse coordinate: " + value);
1356
- return value;
1357
- }
1358
-
1359
- me.applyCanvasGradient = function(el, gradient){
1360
-
1361
- var canvas = me.getCanvas();
1362
- var computedStyle = document.defaultView.getComputedStyle(el, null);
1363
-
1364
- canvas.width = parseInt(computedStyle.width) + parseInt(computedStyle.paddingLeft) + parseInt(computedStyle.paddingRight) + 1; // inserted by Zoltan
1365
- canvas.height = parseInt(computedStyle.height) + parseInt(computedStyle.paddingTop) + parseInt(computedStyle.paddingBottom) + 2; // 1 inserted by Zoltan
1366
- var ctx = canvas.getContext('2d');
1367
-
1368
- //Iterate over the gradients and build them up
1369
-
1370
- var canvasGradient;
1371
- // Linear gradient
1372
- if (gradient.type == 'linear') {
1373
-
1374
-
1375
- canvasGradient = ctx.createLinearGradient(me.parseCoordinate(gradient.x0, canvas.width), me.parseCoordinate(gradient.y0, canvas.height), me.parseCoordinate(gradient.x1, canvas.width), me.parseCoordinate(gradient.y1, canvas.height));
1376
- } // Radial gradient
1377
- else /*if(gradient.type == 'radial')*/ {
1378
- canvasGradient = ctx.createRadialGradient(me.parseCoordinate(gradient.x0, canvas.width), me.parseCoordinate(gradient.y0, canvas.height), gradient.r0, me.parseCoordinate(gradient.x1, canvas.width), me.parseCoordinate(gradient.y1, canvas.height), gradient.r1);
1379
- }
1380
-
1381
- //Add each of the color stops to the gradient
1382
- for (var i = 0; i < gradient.colorStops.length; i++) {
1383
- var cs = gradient.colorStops[i];
1384
-
1385
- canvasGradient.addColorStop(cs.stop, cs.color);
1386
- };
1387
-
1388
- //Paint the gradient
1389
- ctx.fillStyle = canvasGradient;
1390
- ctx.fillRect(0, 0, canvas.width, canvas.height);
1391
-
1392
-
1393
- //Apply the gradient to the selectedElement
1394
- el.style.backgroundImage = "url('" + canvas.toDataURL() + "')";
1395
-
1396
- }
1397
-
1398
- }
1399
-
1400
- function MSFilterList(node){
1401
- var me = this;
1402
-
1403
- me.list = new Array();
1404
- me.node = node;
1405
-
1406
- var reFilterListSplitter = /[\s\S]*\([\s\S]*\)/g;
1407
-
1408
- var styleAttr = node.style;
1409
-
1410
- function init(){
1411
-
1412
- var filterCalls = styleAttr.filter.match(reFilterListSplitter);
1413
-
1414
- if (filterCalls != null) {
1415
-
1416
- for (var i = 0; i < filterCalls.length; i++) {
1417
- var call = filterCalls[i];
1418
-
1419
- me.list.push(new MSFilter(node, call));
1420
-
1421
- }
1422
- }
1423
-
1424
-
1425
- }
1426
-
1427
- me.toString = function(){
1428
- var sb = new StringBuffer();
1429
-
1430
- for (var i = 0; i < me.list.length; i++) {
1431
-
1432
- sb.append(me.list[i].toString());
1433
- if (i < me.list.length - 1) {
1434
- sb.append(',')
1435
- }
1436
- }
1437
- return sb.toString();
1438
- }
1439
-
1440
-
1441
- me.fixFilterStyle = function(){
1442
-
1443
- try {
1444
- me.node.style.filter = me.toString();
1445
- }
1446
- catch (ex) {
1447
- // do nothing.
1448
- }
1449
-
1450
- }
1451
-
1452
- init();
1453
- }
1454
-
1455
- function MSFilter(node, filterCall){
1456
- var me = this;
1457
-
1458
- me.node = node;
1459
- me.filterCall = filterCall;
1460
-
1461
- var reFilterNameSplitter = /progid:([^\(]*)/g;
1462
- var reParameterName = /([a-zA-Z0-9]+\s*)=/g;
1463
-
1464
-
1465
- function init(){
1466
- me.name = me.filterCall.match(reFilterNameSplitter)[0].replace('progid:', '');
1467
-
1468
- //This may not be the best way to do this.
1469
- var parameterString = filterCall.split('(')[1].replace(')', '');
1470
- me.parameters = parameterString.match(reParameterName);
1471
-
1472
- for (var i = 0; i < me.parameters.length; i++) {
1473
- me.parameters[i] = me.parameters[i].replace('=', '');
1474
- }
1475
-
1476
- }
1477
-
1478
- me.toString = function(){
1479
-
1480
- var sb = new StringBuffer();
1481
-
1482
- sb.append(StringHelpers.sprintf('progid:%s(', me.name));
1483
-
1484
- for (var i = 0; i < me.parameters.length; i++) {
1485
- var param = me.parameters[i];
1486
- var filterObj = me.node.filters.item(me.name);
1487
- var paramValue = filterObj[param];
1488
- if (typeof(paramValue) == 'string') {
1489
- sb.append(StringHelpers.sprintf('%s="%s"', param, filterObj[param]));
1490
- } else {
1491
- sb.append(StringHelpers.sprintf('%s=%s', param, filterObj[param]));
1492
- }
1493
-
1494
- if (i != me.parameters.length - 1) {
1495
- sb.append(', ')
1496
- }
1497
- }
1498
- sb.append(')');
1499
-
1500
- return sb.toString();
1501
- }
1502
-
1503
-
1504
-
1505
- init();
1506
- }
1507
-
1508
- var implementation = new function(){
1509
- this.NONE = 0;
1510
-
1511
- // Native Support.
1512
- this.NATIVE = 1;
1513
-
1514
- // Vendor specific prefix implementations
1515
- this.MOZILLA = 2;
1516
- this.WEBKIT = 3;
1517
- this.IE = 4;
1518
- this.OPERA = 5;
1519
-
1520
- // Non CSS3 Workarounds
1521
- this.CANVAS_WORKAROUND = 6;
1522
- this.FILTER_WORKAROUND = 7;
1523
- this.HEX_WORKAROUND = 8;
1524
- }
1525
-
1526
- var colorType = new function () {
1527
- this.BACKGROUND = 0;
1528
- this.FOREGROUND = 1;
1529
- }
1530
-
1531
- /*
1532
- * Extra helper routines
1533
- */
1534
- if (!window.StringHelpers) {
1535
- StringHelpers = new function(){
1536
- var me = this;
1537
-
1538
- // used by the String.prototype.trim()
1539
- me.initWhitespaceRe = /^\s\s*/;
1540
- me.endWhitespaceRe = /\s\s*$/;
1541
- me.whitespaceRe = /\s/;
1542
-
1543
- /*******************************************************************************
1544
- * Function sprintf(format_string,arguments...) Javascript emulation of the C
1545
- * printf function (modifiers and argument types "p" and "n" are not supported
1546
- * due to language restrictions)
1547
- *
1548
- * Copyright 2003 K&L Productions. All rights reserved
1549
- * http://www.klproductions.com
1550
- *
1551
- * Terms of use: This function can be used free of charge IF this header is not
1552
- * modified and remains with the function code.
1553
- *
1554
- * Legal: Use this code at your own risk. K&L Productions assumes NO
1555
- * resposibility for anything.
1556
- ******************************************************************************/
1557
- me.sprintf = function(fstring){
1558
- var pad = function(str, ch, len){
1559
- var ps = '';
1560
- for (var i = 0; i < Math.abs(len); i++)
1561
- ps += ch;
1562
- return len > 0 ? str + ps : ps + str;
1563
- }
1564
- var processFlags = function(flags, width, rs, arg){
1565
- var pn = function(flags, arg, rs){
1566
- if (arg >= 0) {
1567
- if (flags.indexOf(' ') >= 0)
1568
- rs = ' ' + rs;
1569
- else if (flags.indexOf('+') >= 0)
1570
- rs = '+' + rs;
1571
- } else
1572
- rs = '-' + rs;
1573
- return rs;
1574
- }
1575
- var iWidth = parseInt(width, 10);
1576
- if (width.charAt(0) == '0') {
1577
- var ec = 0;
1578
- if (flags.indexOf(' ') >= 0 || flags.indexOf('+') >= 0)
1579
- ec++;
1580
- if (rs.length < (iWidth - ec))
1581
- rs = pad(rs, '0', rs.length - (iWidth - ec));
1582
- return pn(flags, arg, rs);
1583
- }
1584
- rs = pn(flags, arg, rs);
1585
- if (rs.length < iWidth) {
1586
- if (flags.indexOf('-') < 0)
1587
- rs = pad(rs, ' ', rs.length - iWidth);
1588
- else
1589
- rs = pad(rs, ' ', iWidth - rs.length);
1590
- }
1591
- return rs;
1592
- }
1593
- var converters = new Array();
1594
- converters['c'] = function(flags, width, precision, arg){
1595
- if (typeof(arg) == 'number')
1596
- return String.fromCharCode(arg);
1597
- if (typeof(arg) == 'string')
1598
- return arg.charAt(0);
1599
- return '';
1600
- }
1601
- converters['d'] = function(flags, width, precision, arg){
1602
- return converters['i'](flags, width, precision, arg);
1603
- }
1604
- converters['u'] = function(flags, width, precision, arg){
1605
- return converters['i'](flags, width, precision, Math.abs(arg));
1606
- }
1607
- converters['i'] = function(flags, width, precision, arg){
1608
- var iPrecision = parseInt(precision);
1609
- var rs = ((Math.abs(arg)).toString().split('.'))[0];
1610
- if (rs.length < iPrecision)
1611
- rs = pad(rs, ' ', iPrecision - rs.length);
1612
- return processFlags(flags, width, rs, arg);
1613
- }
1614
- converters['E'] = function(flags, width, precision, arg){
1615
- return (converters['e'](flags, width, precision, arg)).toUpperCase();
1616
- }
1617
- converters['e'] = function(flags, width, precision, arg){
1618
- iPrecision = parseInt(precision);
1619
- if (isNaN(iPrecision))
1620
- iPrecision = 6;
1621
- rs = (Math.abs(arg)).toExponential(iPrecision);
1622
- if (rs.indexOf('.') < 0 && flags.indexOf('#') >= 0)
1623
- rs = rs.replace(/^(.*)(e.*)$/, '$1.$2');
1624
- return processFlags(flags, width, rs, arg);
1625
- }
1626
- converters['f'] = function(flags, width, precision, arg){
1627
- iPrecision = parseInt(precision);
1628
- if (isNaN(iPrecision))
1629
- iPrecision = 6;
1630
- rs = (Math.abs(arg)).toFixed(iPrecision);
1631
- if (rs.indexOf('.') < 0 && flags.indexOf('#') >= 0)
1632
- rs = rs + '.';
1633
- return processFlags(flags, width, rs, arg);
1634
- }
1635
- converters['G'] = function(flags, width, precision, arg){
1636
- return (converters['g'](flags, width, precision, arg)).toUpperCase();
1637
- }
1638
- converters['g'] = function(flags, width, precision, arg){
1639
- iPrecision = parseInt(precision);
1640
- absArg = Math.abs(arg);
1641
- rse = absArg.toExponential();
1642
- rsf = absArg.toFixed(6);
1643
- if (!isNaN(iPrecision)) {
1644
- rsep = absArg.toExponential(iPrecision);
1645
- rse = rsep.length < rse.length ? rsep : rse;
1646
- rsfp = absArg.toFixed(iPrecision);
1647
- rsf = rsfp.length < rsf.length ? rsfp : rsf;
1648
- }
1649
- if (rse.indexOf('.') < 0 && flags.indexOf('#') >= 0)
1650
- rse = rse.replace(/^(.*)(e.*)$/, '$1.$2');
1651
- if (rsf.indexOf('.') < 0 && flags.indexOf('#') >= 0)
1652
- rsf = rsf + '.';
1653
- rs = rse.length < rsf.length ? rse : rsf;
1654
- return processFlags(flags, width, rs, arg);
1655
- }
1656
- converters['o'] = function(flags, width, precision, arg){
1657
- var iPrecision = parseInt(precision);
1658
- var rs = Math.round(Math.abs(arg)).toString(8);
1659
- if (rs.length < iPrecision)
1660
- rs = pad(rs, ' ', iPrecision - rs.length);
1661
- if (flags.indexOf('#') >= 0)
1662
- rs = '0' + rs;
1663
- return processFlags(flags, width, rs, arg);
1664
- }
1665
- converters['X'] = function(flags, width, precision, arg){
1666
- return (converters['x'](flags, width, precision, arg)).toUpperCase();
1667
- }
1668
- converters['x'] = function(flags, width, precision, arg){
1669
- var iPrecision = parseInt(precision);
1670
- arg = Math.abs(arg);
1671
- var rs = Math.round(arg).toString(16);
1672
- if (rs.length < iPrecision)
1673
- rs = pad(rs, ' ', iPrecision - rs.length);
1674
- if (flags.indexOf('#') >= 0)
1675
- rs = '0x' + rs;
1676
- return processFlags(flags, width, rs, arg);
1677
- }
1678
- converters['s'] = function(flags, width, precision, arg){
1679
- var iPrecision = parseInt(precision);
1680
- var rs = arg;
1681
- if (rs.length > iPrecision)
1682
- rs = rs.substring(0, iPrecision);
1683
- return processFlags(flags, width, rs, 0);
1684
- }
1685
- farr = fstring.split('%');
1686
- retstr = farr[0];
1687
- fpRE = /^([-+ #]*)(\d*)\.?(\d*)([cdieEfFgGosuxX])(.*)$/;
1688
- for (var i = 1; i < farr.length; i++) {
1689
- fps = fpRE.exec(farr[i]);
1690
- if (!fps)
1691
- continue;
1692
- if (arguments[i] != null)
1693
- retstr += converters[fps[4]](fps[1], fps[2], fps[3], arguments[i]);
1694
- retstr += fps[5];
1695
- }
1696
- return retstr;
1697
- }
1698
-
1699
- /**
1700
- * Take out the first comment inside a block of HTML
1701
- *
1702
- * @param {String} s - an HTML block
1703
- * @return {String} s - the HTML block uncommented.
1704
- */
1705
- me.uncommentHTML = function(s){
1706
- if (s.indexOf('-->') != -1 && s.indexOf('<!--') != -1) {
1707
- return s.replace("<!--", "").replace("-->", "");
1708
- } else {
1709
- return s;
1710
- }
1711
- }
1712
- }
1713
- }
1714
-
1715
- if (!window.XMLHelpers) {
1716
-
1717
- XMLHelpers = new function(){
1718
-
1719
- var me = this;
1720
-
1721
- /**
1722
- * Wrapper for XMLHttpRequest Object. Grabbing data (XML and/or text) from a URL.
1723
- * Grabbing data from a URL. Input is one parameter, url. It returns a request
1724
- * object. Based on code from
1725
- * http://www.xml.com/pub/a/2005/02/09/xml-http-request.html. IE caching problem
1726
- * fix from Wikipedia article http://en.wikipedia.org/wiki/XMLHttpRequest
1727
- *
1728
- * @param {String} url - the URL to retrieve
1729
- * @param {Function} processReqChange - the function/method to call at key events of the URL retrieval.
1730
- * @param {String} method - (optional) "GET" or "POST" (default "GET")
1731
- * @param {String} data - (optional) the CGI data to pass. Default null.
1732
- * @param {boolean} isAsync - (optional) is this call asyncronous. Default true.
1733
- *
1734
- * @return {Object} a XML request object.
1735
- */
1736
- me.getXMLHttpRequest = function(url, processReqChange) //, method, data, isAsync)
1737
- {
1738
- var argv = me.getXMLHttpRequest.arguments;
1739
- var argc = me.getXMLHttpRequest.arguments.length;
1740
- var httpMethod = (argc > 2) ? argv[2] : 'GET';
1741
- var data = (argc > 3) ? argv[3] : "";
1742
- var isAsync = (argc > 4) ? argv[4] : true;
1743
-
1744
- var req;
1745
- // branch for native XMLHttpRequest object
1746
- if (window.XMLHttpRequest) {
1747
- req = new XMLHttpRequest();
1748
- // branch for IE/Windows ActiveX version
1749
- } else if (window.ActiveXObject) {
1750
- try {
1751
- req = new ActiveXObject('Msxml2.XMLHTTP');
1752
- }
1753
- catch (ex) {
1754
- req = new ActiveXObject("Microsoft.XMLHTTP");
1755
- }
1756
- // the browser doesn't support XML HttpRequest. Return null;
1757
- } else {
1758
- return null;
1759
- }
1760
-
1761
- if (isAsync) {
1762
- req.onreadystatechange = processReqChange;
1763
- }
1764
-
1765
- if (httpMethod == "GET" && data != "") {
1766
- url += "?" + data;
1767
- }
1768
-
1769
- req.open(httpMethod, url, isAsync);
1770
-
1771
- //Fixes IE Caching problem
1772
- req.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT");
1773
- req.send(data);
1774
-
1775
- return req;
1776
- }
1777
- }
1778
- }
1779
-
1780
-
1781
- if (!window.CSSHelpers) {
1782
- CSSHelpers = new function(){
1783
- var me = this;
1784
-
1785
- var blankRe = new RegExp('\\s');
1786
-
1787
- /*
1788
- * getComputedStyle: code from http://blog.stchur.com/2006/06/21/css-computed-style/
1789
- */
1790
- me.getComputedStyle = function(elem, style)
1791
- {
1792
- var computedStyle;
1793
- if (typeof elem.currentStyle != 'undefined')
1794
- { computedStyle = elem.currentStyle; }
1795
- else
1796
- { computedStyle = document.defaultView.getComputedStyle(elem, null); }
1797
-
1798
- return computedStyle[style];
1799
- }
1800
-
1801
-
1802
- /**
1803
- * Determines if an HTML object is a member of a specific class.
1804
- * @param {Object} obj - an HTML object.
1805
- * @param {Object} className - the CSS class name.
1806
- */
1807
- me.isMemberOfClass = function(obj, className){
1808
-
1809
- if (blankRe.test(className))
1810
- return false;
1811
-
1812
- var re = new RegExp(getClassReString(className), "g");
1813
-
1814
- return (re.test(obj.className));
1815
-
1816
-
1817
- }
1818
-
1819
- /**
1820
- * Make an HTML object be a member of a certain class.
1821
- *
1822
- * @param {Object} obj - an HTML object
1823
- * @param {String} className - a CSS class name.
1824
- */
1825
- me.addClass = function(obj, className){
1826
- if (blankRe.test(className)) {
1827
- return;
1828
- }
1829
-
1830
- // only add class if the object is not a member of it yet.
1831
- if (!me.isMemberOfClass(obj, className)) {
1832
- obj.className += " " + className;
1833
- }
1834
- }
1835
-
1836
- /**
1837
- * Make an HTML object *not* be a member of a certain class.
1838
- *
1839
- * @param {Object} obj - an HTML object
1840
- * @param {Object} className - a CSS class name.
1841
- */
1842
- me.removeClass = function(obj, className){
1843
-
1844
- if (blankRe.test(className)) {
1845
- return;
1846
- }
1847
-
1848
-
1849
- var re = new RegExp(getClassReString(className), "g");
1850
-
1851
- var oldClassName = obj.className;
1852
-
1853
-
1854
- if (obj.className) {
1855
- obj.className = oldClassName.replace(re, '');
1856
- }
1857
-
1858
-
1859
- }
1860
-
1861
- function getClassReString(className) {
1862
- return '\\s'+className+'\\s|^' + className + '\\s|\\s' + className + '$|' + '^' + className +'$';
1863
- }
1864
-
1865
- /**
1866
- * Given an HTML element, find all child nodes of a specific class.
1867
- *
1868
- * With ideas from Jonathan Snook
1869
- * (http://snook.ca/archives/javascript/your_favourite_1/)
1870
- * Since this was presented within a post on this site, it is for the
1871
- * public domain according to the site's copyright statement.
1872
- *
1873
- * @param {Object} obj - an HTML element. If you want to search a whole document, set
1874
- * this to the document object.
1875
- * @param {String} className - the class name of the objects to return
1876
- * @return {Array} - the list of objects of class cls.
1877
- */
1878
- me.getElementsByClassName = function (obj, className)
1879
- {
1880
- if (obj.getElementsByClassName) {
1881
- return DOMHelpers.nodeListToArray(obj.getElementsByClassName(className))
1882
- }
1883
- else {
1884
- var a = [];
1885
- var re = new RegExp(getClassReString(className));
1886
- var els = DOMHelpers.getAllDescendants(obj);
1887
- for (var i = 0, j = els.length; i < j; i++) {
1888
- if (re.test(els[i].className)) {
1889
- a.push(els[i]);
1890
-
1891
- }
1892
- }
1893
- return a;
1894
- }
1895
- }
1896
-
1897
- /**
1898
- * Generates a regular expression string that can be used to detect a class name
1899
- * in a tag's class attribute. It is used by a few methods, so I
1900
- * centralized it.
1901
- *
1902
- * @param {String} className - a name of a CSS class.
1903
- */
1904
- function getClassReString(className){
1905
- return '\\s' + className + '\\s|^' + className + '\\s|\\s' + className + '$|' + '^' + className + '$';
1906
- }
1907
-
1908
-
1909
- }
1910
- }
1911
-
1912
-
1913
- /*
1914
- * Adding trim method to String Object. Ideas from
1915
- * http://www.faqts.com/knowledge_base/view.phtml/aid/1678/fid/1 and
1916
- * http://blog.stevenlevithan.com/archives/faster-trim-javascript
1917
- */
1918
- String.prototype.trim = function(){
1919
- var str = this;
1920
-
1921
- // The first method is faster on long strings than the second and
1922
- // vice-versa.
1923
- if (this.length > 6000) {
1924
- str = this.replace(StringHelpers.initWhitespaceRe, '');
1925
- var i = str.length;
1926
- while (StringHelpers.whitespaceRe.test(str.charAt(--i)))
1927
- ;
1928
- return str.slice(0, i + 1);
1929
- } else {
1930
- return this.replace(StringHelpers.initWhitespaceRe, '').replace(StringHelpers.endWhitespaceRe, '');
1931
- }
1932
-
1933
-
1934
- };
1935
-
1936
- if (!window.DOMHelpers) {
1937
-
1938
- DOMHelpers = new function () {
1939
- var me = this;
1940
-
1941
- /**
1942
- * Returns all children of an element. Needed if it is necessary to do
1943
- * the equivalent of getElementsByTagName('*') for IE5 for Windows.
1944
- *
1945
- * @param {Object} e - an HTML object.
1946
- */
1947
- me.getAllDescendants = function(obj) {
1948
- return obj.all ? obj.all : obj.getElementsByTagName('*');
1949
- }
1950
-
1951
- /******
1952
- * Converts a DOM live node list to a static/dead array. Good when you don't
1953
- * want the thing you are iterating in a for loop changing as the DOM changes.
1954
- *
1955
- * @param {Object} nodeList - a node list (like one returned by document.getElementsByTagName)
1956
- * @return {Array} - an array of nodes.
1957
- *
1958
- *******/
1959
- me.nodeListToArray = function (nodeList)
1960
- {
1961
- var ary = [];
1962
- for(var i=0, len = nodeList.length; i < len; i++)
1963
- {
1964
- ary.push(nodeList[i]);
1965
- }
1966
- return ary;
1967
- }
1968
- }
1969
- }
1970
-
1971
- //+ Jonas Raoni Soares Silva
1972
- //@ http://jsfromhell.com/string/capitalize [v1.0]
1973
-
1974
- String.prototype.capitalize = function(){ //v1.0
1975
- return this.charAt(0).toUpperCase() + this.substr(1);
1976
-
1977
- };
1978
-
1979
-
1980
- /*
1981
- * stringBuffer.js - ideas from
1982
- * http://www.multitask.com.au/people/dion/archives/000354.html
1983
- */
1984
- function StringBuffer(){
1985
- var me = this;
1986
-
1987
- var buffer = [];
1988
-
1989
-
1990
- me.append = function(string){
1991
- buffer.push(string);
1992
- return me;
1993
- }
1994
-
1995
- me.appendBuffer = function(bufferToAppend){
1996
- buffer = buffer.concat(bufferToAppend);
1997
- }
1998
-
1999
- me.toString = function(){
2000
- return buffer.join("");
2001
- }
2002
-
2003
- me.getLength = function(){
2004
- return buffer.length;
2005
- }
2006
-
2007
- me.flush = function(){
2008
- buffer.length = 0;
2009
- }
2010
-
2011
- }
2012
-
2013
- /**
2014
- * A class to parse color values
2015
- * @author Stoyan Stefanov <sstoo@gmail.com> (with modifications)
2016
- * @link http://www.phpied.com/rgb-color-parser-in-javascript/
2017
- * @license Use it if you like it
2018
- */
2019
- function RGBColor(color_string){
2020
-
2021
- var me = this;
2022
-
2023
-
2024
-
2025
- me.ok = false;
2026
-
2027
- // strip any leading #
2028
- if (color_string.charAt(0) == '#') { // remove # if any
2029
- color_string = color_string.substr(1, 6);
2030
- }
2031
-
2032
- color_string = color_string.replace(/ /g, '');
2033
- color_string = color_string.toLowerCase();
2034
-
2035
- // before getting into regexps, try simple matches
2036
- // and overwrite the input
2037
- var simple_colors = {
2038
- aliceblue: 'f0f8ff',
2039
- antiquewhite: 'faebd7',
2040
- aqua: '00ffff',
2041
- aquamarine: '7fffd4',
2042
- azure: 'f0ffff',
2043
- beige: 'f5f5dc',
2044
- bisque: 'ffe4c4',
2045
- black: '000000',
2046
- blanchedalmond: 'ffebcd',
2047
- blue: '0000ff',
2048
- blueviolet: '8a2be2',
2049
- brown: 'a52a2a',
2050
- burlywood: 'deb887',
2051
- cadetblue: '5f9ea0',
2052
- chartreuse: '7fff00',
2053
- chocolate: 'd2691e',
2054
- coral: 'ff7f50',
2055
- cornflowerblue: '6495ed',
2056
- cornsilk: 'fff8dc',
2057
- crimson: 'dc143c',
2058
- cyan: '00ffff',
2059
- darkblue: '00008b',
2060
- darkcyan: '008b8b',
2061
- darkgoldenrod: 'b8860b',
2062
- darkgray: 'a9a9a9',
2063
- darkgreen: '006400',
2064
- darkkhaki: 'bdb76b',
2065
- darkmagenta: '8b008b',
2066
- darkolivegreen: '556b2f',
2067
- darkorange: 'ff8c00',
2068
- darkorchid: '9932cc',
2069
- darkred: '8b0000',
2070
- darksalmon: 'e9967a',
2071
- darkseagreen: '8fbc8f',
2072
- darkslateblue: '483d8b',
2073
- darkslategray: '2f4f4f',
2074
- darkturquoise: '00ced1',
2075
- darkviolet: '9400d3',
2076
- deeppink: 'ff1493',
2077
- deepskyblue: '00bfff',
2078
- dimgray: '696969',
2079
- dodgerblue: '1e90ff',
2080
- feldspar: 'd19275',
2081
- firebrick: 'b22222',
2082
- floralwhite: 'fffaf0',
2083
- forestgreen: '228b22',
2084
- fuchsia: 'ff00ff',
2085
- gainsboro: 'dcdcdc',
2086
- ghostwhite: 'f8f8ff',
2087
- gold: 'ffd700',
2088
- goldenrod: 'daa520',
2089
- gray: '808080',
2090
- green: '008000',
2091
- greenyellow: 'adff2f',
2092
- honeydew: 'f0fff0',
2093
- hotpink: 'ff69b4',
2094
- indianred: 'cd5c5c',
2095
- indigo: '4b0082',
2096
- ivory: 'fffff0',
2097
- khaki: 'f0e68c',
2098
- lavender: 'e6e6fa',
2099
- lavenderblush: 'fff0f5',
2100
- lawngreen: '7cfc00',
2101
- lemonchiffon: 'fffacd',
2102
- lightblue: 'add8e6',
2103
- lightcoral: 'f08080',
2104
- lightcyan: 'e0ffff',
2105
- lightgoldenrodyellow: 'fafad2',
2106
- lightgrey: 'd3d3d3',
2107
- lightgreen: '90ee90',
2108
- lightpink: 'ffb6c1',
2109
- lightsalmon: 'ffa07a',
2110
- lightseagreen: '20b2aa',
2111
- lightskyblue: '87cefa',
2112
- lightslateblue: '8470ff',
2113
- lightslategray: '778899',
2114
- lightsteelblue: 'b0c4de',
2115
- lightyellow: 'ffffe0',
2116
- lime: '00ff00',
2117
- limegreen: '32cd32',
2118
- linen: 'faf0e6',
2119
- magenta: 'ff00ff',
2120
- maroon: '800000',
2121
- mediumaquamarine: '66cdaa',
2122
- mediumblue: '0000cd',
2123
- mediumorchid: 'ba55d3',
2124
- mediumpurple: '9370d8',
2125
- mediumseagreen: '3cb371',
2126
- mediumslateblue: '7b68ee',
2127
- mediumspringgreen: '00fa9a',
2128
- mediumturquoise: '48d1cc',
2129
- mediumvioletred: 'c71585',
2130
- midnightblue: '191970',
2131
- mintcream: 'f5fffa',
2132
- mistyrose: 'ffe4e1',
2133
- moccasin: 'ffe4b5',
2134
- navajowhite: 'ffdead',
2135
- navy: '000080',
2136
- oldlace: 'fdf5e6',
2137
- olive: '808000',
2138
- olivedrab: '6b8e23',
2139
- orange: 'ffa500',
2140
- orangered: 'ff4500',
2141
- orchid: 'da70d6',
2142
- palegoldenrod: 'eee8aa',
2143
- palegreen: '98fb98',
2144
- paleturquoise: 'afeeee',
2145
- palevioletred: 'd87093',
2146
- papayawhip: 'ffefd5',
2147
- peachpuff: 'ffdab9',
2148
- peru: 'cd853f',
2149
- pink: 'ffc0cb',
2150
- plum: 'dda0dd',
2151
- powderblue: 'b0e0e6',
2152
- purple: '800080',
2153
- red: 'ff0000',
2154
- rosybrown: 'bc8f8f',
2155
- royalblue: '4169e1',
2156
- saddlebrown: '8b4513',
2157
- salmon: 'fa8072',
2158
- sandybrown: 'f4a460',
2159
- seagreen: '2e8b57',
2160
- seashell: 'fff5ee',
2161
- sienna: 'a0522d',
2162
- silver: 'c0c0c0',
2163
- skyblue: '87ceeb',
2164
- slateblue: '6a5acd',
2165
- slategray: '708090',
2166
- snow: 'fffafa',
2167
- springgreen: '00ff7f',
2168
- steelblue: '4682b4',
2169
- tan: 'd2b48c',
2170
- teal: '008080',
2171
- metle: 'd8bfd8',
2172
- tomato: 'ff6347',
2173
- turquoise: '40e0d0',
2174
- violet: 'ee82ee',
2175
- violetred: 'd02090',
2176
- wheat: 'f5deb3',
2177
- white: 'ffffff',
2178
- whitesmoke: 'f5f5f5',
2179
- yellow: 'ffff00',
2180
- yellowgreen: '9acd32'
2181
- };
2182
- for (var key in simple_colors) {
2183
- if (color_string == key) {
2184
- color_string = simple_colors[key];
2185
- }
2186
- }
2187
- // emd of simple type-in colors
2188
-
2189
- // array of color definition objects
2190
- var color_defs = [{
2191
- re: /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/,
2192
- example: ['rgb(123, 234, 45)', 'rgb(255,234,245)'],
2193
- process: function(bits){
2194
- return [parseInt(bits[1]), parseInt(bits[2]), parseInt(bits[3])];
2195
- }
2196
- }, {
2197
- re: /^(\w{2})(\w{2})(\w{2})$/,
2198
- example: ['#00ff00', '336699'],
2199
- process: function(bits){
2200
- return [parseInt(bits[1], 16), parseInt(bits[2], 16), parseInt(bits[3], 16)];
2201
- }
2202
- }, {
2203
- re: /^(\w{1})(\w{1})(\w{1})$/,
2204
- example: ['#fb0', 'f0f'],
2205
- process: function(bits){
2206
- return [parseInt(bits[1] + bits[1], 16), parseInt(bits[2] + bits[2], 16), parseInt(bits[3] + bits[3], 16)];
2207
- }
2208
- }, {
2209
- re: /^rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(0{0,1}\.\d{1,}|0\.{0,}0*|1\.{0,}0*)\)$/,
2210
- example: ['rgba(123, 234, 45, 22)', 'rgba(255, 234,245, 34)'],
2211
- process: function(bits){
2212
- return [parseInt(bits[1]), parseInt(bits[2]), parseInt(bits[3]), parseFloat(bits[4])];
2213
- }
2214
- }, {
2215
- re: /^hsla\((\d{1,3}),\s*(\d{1,3}%),\s*(\d{1,3}%),\s*(0{0,1}\.\d{1,}|0\.{0,}0*|1\.{0,}0*)\)$/,
2216
- example: ['hsla(0,100%,50%,0.2)'],
2217
- process: function(bits){
2218
- var result = hsl2rgb(parseInt(bits[1]), parseInt(bits[2]), parseInt(bits[3]), parseFloat(bits[4]));
2219
-
2220
- return [result.r, result.g, result.b, parseFloat(bits[4])];
2221
-
2222
- }
2223
- }, {
2224
- re: /^hsl\((\d{1,3}),\s*(\d{1,3}%),\s*(\d{1,3}%)\)$/,
2225
- example: ['hsl(0,100%,50%)'],
2226
- process: function(bits){
2227
- var result = hsl2rgb(parseInt(bits[1]), parseInt(bits[2]), parseInt(bits[3]), 1);
2228
-
2229
- return [result.r, result.g, result.b, 1];
2230
-
2231
- }
2232
- }];
2233
-
2234
- // search through the definitions to find a match
2235
- for (var i = 0; i < color_defs.length; i++) {
2236
- var re = color_defs[i].re;
2237
- var processor = color_defs[i].process;
2238
- var bits = re.exec(color_string);
2239
- if (bits) {
2240
- channels = processor(bits);
2241
- me.r = channels[0];
2242
- me.g = channels[1];
2243
- me.b = channels[2];
2244
- me.a = channels[3];
2245
- me.ok = true;
2246
- }
2247
-
2248
- }
2249
-
2250
- // validate/cleanup values
2251
- me.r = (me.r < 0 || isNaN(me.r)) ? 0 : ((me.r > 255) ? 255 : me.r);
2252
- me.g = (me.g < 0 || isNaN(me.g)) ? 0 : ((me.g > 255) ? 255 : me.g);
2253
- me.b = (me.b < 0 || isNaN(me.b)) ? 0 : ((me.b > 255) ? 255 : me.b);
2254
-
2255
-
2256
-
2257
- me.a = (isNaN(me.a)) ? 1 : ((me.a > 255) ? 255 : (me.a < 0) ? 0 : me.a);
2258
-
2259
-
2260
-
2261
- // some getters
2262
- me.toRGB = function(){
2263
- return 'rgb(' + me.r + ', ' + me.g + ', ' + me.b + ')';
2264
- }
2265
-
2266
- // some getters
2267
- me.toRGBA = function(){
2268
- return 'rgba(' + me.r + ', ' + me.g + ', ' + me.b + ', ' + me.a + ')';
2269
- }
2270
-
2271
- /**
2272
- * Converts an RGB color value to HSV. Conversion formula
2273
- * adapted from http://en.wikipedia.org/wiki/HSV_color_space.
2274
- * Assumes r, g, and b are contained in the set [0, 255] and
2275
- * returns h, s, and v in the set [0, 1].
2276
- *
2277
- * This routine by Michael Jackson (not *that* one),
2278
- * from http://www.mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
2279
- *
2280
- * @param Number r The red color value
2281
- * @param Number g The green color value
2282
- * @param Number b The blue color value
2283
- * @return Array The HSV representation
2284
- */
2285
- me.toHSV = function(){
2286
- var r = me.r / 255, g = me.g / 255, b = me.b / 255;
2287
- var max = Math.max(r, g, b), min = Math.min(r, g, b);
2288
- var h, s, v = max;
2289
-
2290
- var d = max - min;
2291
- s = max == 0 ? 0 : d / max;
2292
-
2293
- if (max == min) {
2294
- h = 0; // achromatic
2295
- } else {
2296
- switch (max) {
2297
- case r:
2298
- h = (g - b) / d + (g < b ? 6 : 0);
2299
- break;
2300
- case g:
2301
- h = (b - r) / d + 2;
2302
- break;
2303
- case b:
2304
- h = (r - g) / d + 4;
2305
- break;
2306
- }
2307
- h /= 6;
2308
- }
2309
-
2310
- return {
2311
- h: h,
2312
- s: s,
2313
- v: v
2314
- };
2315
- }
2316
-
2317
- /*
2318
- * hsl2rgb from http://codingforums.com/showthread.php?t=11156
2319
- * code by Jason Karl Davis (http://www.jasonkarldavis.com)
2320
- */
2321
- function hsl2rgb(h, s, l) {
2322
- var m1, m2, hue;
2323
- var r, g, b
2324
- s /=100;
2325
- l /= 100;
2326
- if (s == 0)
2327
- r = g = b = (l * 255);
2328
- else {
2329
- if (l <= 0.5)
2330
- m2 = l * (s + 1);
2331
- else
2332
- m2 = l + s - l * s;
2333
- m1 = l * 2 - m2;
2334
- hue = h / 360;
2335
- r = HueToRgb(m1, m2, hue + 1/3);
2336
- g = HueToRgb(m1, m2, hue);
2337
- b = HueToRgb(m1, m2, hue - 1/3);
2338
- }
2339
- return {r: Math.round(r), g: Math.round(g), b: Math.round(b)};
2340
- }
2341
-
2342
- function HueToRgb(m1, m2, hue) {
2343
- var v;
2344
- if (hue < 0)
2345
- hue += 1;
2346
- else if (hue > 1)
2347
- hue -= 1;
2348
-
2349
- if (6 * hue < 1)
2350
- v = m1 + (m2 - m1) * hue * 6;
2351
- else if (2 * hue < 1)
2352
- v = m2;
2353
- else if (3 * hue < 2)
2354
- v = m1 + (m2 - m1) * (2/3 - hue) * 6;
2355
- else
2356
- v = m1;
2357
-
2358
- return 255 * v;
2359
- }
2360
-
2361
-
2362
-
2363
- me.toHex = function(){
2364
- var r = me.r.toString(16);
2365
- var g = me.g.toString(16);
2366
- var b = me.b.toString(16);
2367
-
2368
- var a = Math.floor((me.a * 255)).toString(16);
2369
-
2370
- if (r.length == 1)
2371
- r = '0' + r;
2372
- if (g.length == 1)
2373
- g = '0' + g;
2374
- if (b.length == 1)
2375
- b = '0' + b;
2376
-
2377
-
2378
- if (a == 'ff') {
2379
- a = '';
2380
- } else if (a.length == 1) {
2381
- a = '0' + a;
2382
- }
2383
- return '#' + a + r + g + b;
2384
- }
2385
-
2386
-
2387
-
2388
- }
2389
-
2390
- document.write('<style type="text/css">.cssSandpaper-initiallyHidden { visibility: hidden;} </style>');
2391
-
2392
-
2393
-
2394
- EventHelpers.addPageLoadEvent('cssSandpaper.init')
2395
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/dompdf/www/cssSandpaper/js/jcoglan.com/sylvester.js DELETED
@@ -1 +0,0 @@
1
- eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('9 17={3i:\'0.1.3\',16:1e-6};l v(){}v.23={e:l(i){8(i<1||i>7.4.q)?w:7.4[i-1]},2R:l(){8 7.4.q},1u:l(){8 F.1x(7.2u(7))},24:l(a){9 n=7.4.q;9 V=a.4||a;o(n!=V.q){8 1L}J{o(F.13(7.4[n-1]-V[n-1])>17.16){8 1L}}H(--n);8 2x},1q:l(){8 v.u(7.4)},1b:l(a){9 b=[];7.28(l(x,i){b.19(a(x,i))});8 v.u(b)},28:l(a){9 n=7.4.q,k=n,i;J{i=k-n;a(7.4[i],i+1)}H(--n)},2q:l(){9 r=7.1u();o(r===0){8 7.1q()}8 7.1b(l(x){8 x/r})},1C:l(a){9 V=a.4||a;9 n=7.4.q,k=n,i;o(n!=V.q){8 w}9 b=0,1D=0,1F=0;7.28(l(x,i){b+=x*V[i-1];1D+=x*x;1F+=V[i-1]*V[i-1]});1D=F.1x(1D);1F=F.1x(1F);o(1D*1F===0){8 w}9 c=b/(1D*1F);o(c<-1){c=-1}o(c>1){c=1}8 F.37(c)},1m:l(a){9 b=7.1C(a);8(b===w)?w:(b<=17.16)},34:l(a){9 b=7.1C(a);8(b===w)?w:(F.13(b-F.1A)<=17.16)},2k:l(a){9 b=7.2u(a);8(b===w)?w:(F.13(b)<=17.16)},2j:l(a){9 V=a.4||a;o(7.4.q!=V.q){8 w}8 7.1b(l(x,i){8 x+V[i-1]})},2C:l(a){9 V=a.4||a;o(7.4.q!=V.q){8 w}8 7.1b(l(x,i){8 x-V[i-1]})},22:l(k){8 7.1b(l(x){8 x*k})},x:l(k){8 7.22(k)},2u:l(a){9 V=a.4||a;9 i,2g=0,n=7.4.q;o(n!=V.q){8 w}J{2g+=7.4[n-1]*V[n-1]}H(--n);8 2g},2f:l(a){9 B=a.4||a;o(7.4.q!=3||B.q!=3){8 w}9 A=7.4;8 v.u([(A[1]*B[2])-(A[2]*B[1]),(A[2]*B[0])-(A[0]*B[2]),(A[0]*B[1])-(A[1]*B[0])])},2A:l(){9 m=0,n=7.4.q,k=n,i;J{i=k-n;o(F.13(7.4[i])>F.13(m)){m=7.4[i]}}H(--n);8 m},2Z:l(x){9 a=w,n=7.4.q,k=n,i;J{i=k-n;o(a===w&&7.4[i]==x){a=i+1}}H(--n);8 a},3g:l(){8 S.2X(7.4)},2d:l(){8 7.1b(l(x){8 F.2d(x)})},2V:l(x){8 7.1b(l(y){8(F.13(y-x)<=17.16)?x:y})},1o:l(a){o(a.K){8 a.1o(7)}9 V=a.4||a;o(V.q!=7.4.q){8 w}9 b=0,2b;7.28(l(x,i){2b=x-V[i-1];b+=2b*2b});8 F.1x(b)},3a:l(a){8 a.1h(7)},2T:l(a){8 a.1h(7)},1V:l(t,a){9 V,R,x,y,z;2S(7.4.q){27 2:V=a.4||a;o(V.q!=2){8 w}R=S.1R(t).4;x=7.4[0]-V[0];y=7.4[1]-V[1];8 v.u([V[0]+R[0][0]*x+R[0][1]*y,V[1]+R[1][0]*x+R[1][1]*y]);1I;27 3:o(!a.U){8 w}9 C=a.1r(7).4;R=S.1R(t,a.U).4;x=7.4[0]-C[0];y=7.4[1]-C[1];z=7.4[2]-C[2];8 v.u([C[0]+R[0][0]*x+R[0][1]*y+R[0][2]*z,C[1]+R[1][0]*x+R[1][1]*y+R[1][2]*z,C[2]+R[2][0]*x+R[2][1]*y+R[2][2]*z]);1I;2P:8 w}},1t:l(a){o(a.K){9 P=7.4.2O();9 C=a.1r(P).4;8 v.u([C[0]+(C[0]-P[0]),C[1]+(C[1]-P[1]),C[2]+(C[2]-(P[2]||0))])}1d{9 Q=a.4||a;o(7.4.q!=Q.q){8 w}8 7.1b(l(x,i){8 Q[i-1]+(Q[i-1]-x)})}},1N:l(){9 V=7.1q();2S(V.4.q){27 3:1I;27 2:V.4.19(0);1I;2P:8 w}8 V},2n:l(){8\'[\'+7.4.2K(\', \')+\']\'},26:l(a){7.4=(a.4||a).2O();8 7}};v.u=l(a){9 V=25 v();8 V.26(a)};v.i=v.u([1,0,0]);v.j=v.u([0,1,0]);v.k=v.u([0,0,1]);v.2J=l(n){9 a=[];J{a.19(F.2F())}H(--n);8 v.u(a)};v.1j=l(n){9 a=[];J{a.19(0)}H(--n);8 v.u(a)};l S(){}S.23={e:l(i,j){o(i<1||i>7.4.q||j<1||j>7.4[0].q){8 w}8 7.4[i-1][j-1]},33:l(i){o(i>7.4.q){8 w}8 v.u(7.4[i-1])},2E:l(j){o(j>7.4[0].q){8 w}9 a=[],n=7.4.q,k=n,i;J{i=k-n;a.19(7.4[i][j-1])}H(--n);8 v.u(a)},2R:l(){8{2D:7.4.q,1p:7.4[0].q}},2D:l(){8 7.4.q},1p:l(){8 7.4[0].q},24:l(a){9 M=a.4||a;o(1g(M[0][0])==\'1f\'){M=S.u(M).4}o(7.4.q!=M.q||7.4[0].q!=M[0].q){8 1L}9 b=7.4.q,15=b,i,G,10=7.4[0].q,j;J{i=15-b;G=10;J{j=10-G;o(F.13(7.4[i][j]-M[i][j])>17.16){8 1L}}H(--G)}H(--b);8 2x},1q:l(){8 S.u(7.4)},1b:l(a){9 b=[],12=7.4.q,15=12,i,G,10=7.4[0].q,j;J{i=15-12;G=10;b[i]=[];J{j=10-G;b[i][j]=a(7.4[i][j],i+1,j+1)}H(--G)}H(--12);8 S.u(b)},2i:l(a){9 M=a.4||a;o(1g(M[0][0])==\'1f\'){M=S.u(M).4}8(7.4.q==M.q&&7.4[0].q==M[0].q)},2j:l(a){9 M=a.4||a;o(1g(M[0][0])==\'1f\'){M=S.u(M).4}o(!7.2i(M)){8 w}8 7.1b(l(x,i,j){8 x+M[i-1][j-1]})},2C:l(a){9 M=a.4||a;o(1g(M[0][0])==\'1f\'){M=S.u(M).4}o(!7.2i(M)){8 w}8 7.1b(l(x,i,j){8 x-M[i-1][j-1]})},2B:l(a){9 M=a.4||a;o(1g(M[0][0])==\'1f\'){M=S.u(M).4}8(7.4[0].q==M.q)},22:l(a){o(!a.4){8 7.1b(l(x){8 x*a})}9 b=a.1u?2x:1L;9 M=a.4||a;o(1g(M[0][0])==\'1f\'){M=S.u(M).4}o(!7.2B(M)){8 w}9 d=7.4.q,15=d,i,G,10=M[0].q,j;9 e=7.4[0].q,4=[],21,20,c;J{i=15-d;4[i]=[];G=10;J{j=10-G;21=0;20=e;J{c=e-20;21+=7.4[i][c]*M[c][j]}H(--20);4[i][j]=21}H(--G)}H(--d);9 M=S.u(4);8 b?M.2E(1):M},x:l(a){8 7.22(a)},32:l(a,b,c,d){9 e=[],12=c,i,G,j;9 f=7.4.q,1p=7.4[0].q;J{i=c-12;e[i]=[];G=d;J{j=d-G;e[i][j]=7.4[(a+i-1)%f][(b+j-1)%1p]}H(--G)}H(--12);8 S.u(e)},31:l(){9 a=7.4.q,1p=7.4[0].q;9 b=[],12=1p,i,G,j;J{i=1p-12;b[i]=[];G=a;J{j=a-G;b[i][j]=7.4[j][i]}H(--G)}H(--12);8 S.u(b)},1y:l(){8(7.4.q==7.4[0].q)},2A:l(){9 m=0,12=7.4.q,15=12,i,G,10=7.4[0].q,j;J{i=15-12;G=10;J{j=10-G;o(F.13(7.4[i][j])>F.13(m)){m=7.4[i][j]}}H(--G)}H(--12);8 m},2Z:l(x){9 a=w,12=7.4.q,15=12,i,G,10=7.4[0].q,j;J{i=15-12;G=10;J{j=10-G;o(7.4[i][j]==x){8{i:i+1,j:j+1}}}H(--G)}H(--12);8 w},30:l(){o(!7.1y){8 w}9 a=[],n=7.4.q,k=n,i;J{i=k-n;a.19(7.4[i][i])}H(--n);8 v.u(a)},1K:l(){9 M=7.1q(),1c;9 n=7.4.q,k=n,i,1s,1n=7.4[0].q,p;J{i=k-n;o(M.4[i][i]==0){2e(j=i+1;j<k;j++){o(M.4[j][i]!=0){1c=[];1s=1n;J{p=1n-1s;1c.19(M.4[i][p]+M.4[j][p])}H(--1s);M.4[i]=1c;1I}}}o(M.4[i][i]!=0){2e(j=i+1;j<k;j++){9 a=M.4[j][i]/M.4[i][i];1c=[];1s=1n;J{p=1n-1s;1c.19(p<=i?0:M.4[j][p]-M.4[i][p]*a)}H(--1s);M.4[j]=1c}}}H(--n);8 M},3h:l(){8 7.1K()},2z:l(){o(!7.1y()){8 w}9 M=7.1K();9 a=M.4[0][0],n=M.4.q-1,k=n,i;J{i=k-n+1;a=a*M.4[i][i]}H(--n);8 a},3f:l(){8 7.2z()},2y:l(){8(7.1y()&&7.2z()===0)},2Y:l(){o(!7.1y()){8 w}9 a=7.4[0][0],n=7.4.q-1,k=n,i;J{i=k-n+1;a+=7.4[i][i]}H(--n);8 a},3e:l(){8 7.2Y()},1Y:l(){9 M=7.1K(),1Y=0;9 a=7.4.q,15=a,i,G,10=7.4[0].q,j;J{i=15-a;G=10;J{j=10-G;o(F.13(M.4[i][j])>17.16){1Y++;1I}}H(--G)}H(--a);8 1Y},3d:l(){8 7.1Y()},2W:l(a){9 M=a.4||a;o(1g(M[0][0])==\'1f\'){M=S.u(M).4}9 T=7.1q(),1p=T.4[0].q;9 b=T.4.q,15=b,i,G,10=M[0].q,j;o(b!=M.q){8 w}J{i=15-b;G=10;J{j=10-G;T.4[i][1p+j]=M[i][j]}H(--G)}H(--b);8 T},2w:l(){o(!7.1y()||7.2y()){8 w}9 a=7.4.q,15=a,i,j;9 M=7.2W(S.I(a)).1K();9 b,1n=M.4[0].q,p,1c,2v;9 c=[],2c;J{i=a-1;1c=[];b=1n;c[i]=[];2v=M.4[i][i];J{p=1n-b;2c=M.4[i][p]/2v;1c.19(2c);o(p>=15){c[i].19(2c)}}H(--b);M.4[i]=1c;2e(j=0;j<i;j++){1c=[];b=1n;J{p=1n-b;1c.19(M.4[j][p]-M.4[i][p]*M.4[j][i])}H(--b);M.4[j]=1c}}H(--a);8 S.u(c)},3c:l(){8 7.2w()},2d:l(){8 7.1b(l(x){8 F.2d(x)})},2V:l(x){8 7.1b(l(p){8(F.13(p-x)<=17.16)?x:p})},2n:l(){9 a=[];9 n=7.4.q,k=n,i;J{i=k-n;a.19(v.u(7.4[i]).2n())}H(--n);8 a.2K(\'\\n\')},26:l(a){9 i,4=a.4||a;o(1g(4[0][0])!=\'1f\'){9 b=4.q,15=b,G,10,j;7.4=[];J{i=15-b;G=4[i].q;10=G;7.4[i]=[];J{j=10-G;7.4[i][j]=4[i][j]}H(--G)}H(--b);8 7}9 n=4.q,k=n;7.4=[];J{i=k-n;7.4.19([4[i]])}H(--n);8 7}};S.u=l(a){9 M=25 S();8 M.26(a)};S.I=l(n){9 a=[],k=n,i,G,j;J{i=k-n;a[i]=[];G=k;J{j=k-G;a[i][j]=(i==j)?1:0}H(--G)}H(--n);8 S.u(a)};S.2X=l(a){9 n=a.q,k=n,i;9 M=S.I(n);J{i=k-n;M.4[i][i]=a[i]}H(--n);8 M};S.1R=l(b,a){o(!a){8 S.u([[F.1H(b),-F.1G(b)],[F.1G(b),F.1H(b)]])}9 d=a.1q();o(d.4.q!=3){8 w}9 e=d.1u();9 x=d.4[0]/e,y=d.4[1]/e,z=d.4[2]/e;9 s=F.1G(b),c=F.1H(b),t=1-c;8 S.u([[t*x*x+c,t*x*y-s*z,t*x*z+s*y],[t*x*y+s*z,t*y*y+c,t*y*z-s*x],[t*x*z-s*y,t*y*z+s*x,t*z*z+c]])};S.3b=l(t){9 c=F.1H(t),s=F.1G(t);8 S.u([[1,0,0],[0,c,-s],[0,s,c]])};S.39=l(t){9 c=F.1H(t),s=F.1G(t);8 S.u([[c,0,s],[0,1,0],[-s,0,c]])};S.38=l(t){9 c=F.1H(t),s=F.1G(t);8 S.u([[c,-s,0],[s,c,0],[0,0,1]])};S.2J=l(n,m){8 S.1j(n,m).1b(l(){8 F.2F()})};S.1j=l(n,m){9 a=[],12=n,i,G,j;J{i=n-12;a[i]=[];G=m;J{j=m-G;a[i][j]=0}H(--G)}H(--12);8 S.u(a)};l 14(){}14.23={24:l(a){8(7.1m(a)&&7.1h(a.K))},1q:l(){8 14.u(7.K,7.U)},2U:l(a){9 V=a.4||a;8 14.u([7.K.4[0]+V[0],7.K.4[1]+V[1],7.K.4[2]+(V[2]||0)],7.U)},1m:l(a){o(a.W){8 a.1m(7)}9 b=7.U.1C(a.U);8(F.13(b)<=17.16||F.13(b-F.1A)<=17.16)},1o:l(a){o(a.W){8 a.1o(7)}o(a.U){o(7.1m(a)){8 7.1o(a.K)}9 N=7.U.2f(a.U).2q().4;9 A=7.K.4,B=a.K.4;8 F.13((A[0]-B[0])*N[0]+(A[1]-B[1])*N[1]+(A[2]-B[2])*N[2])}1d{9 P=a.4||a;9 A=7.K.4,D=7.U.4;9 b=P[0]-A[0],2a=P[1]-A[1],29=(P[2]||0)-A[2];9 c=F.1x(b*b+2a*2a+29*29);o(c===0)8 0;9 d=(b*D[0]+2a*D[1]+29*D[2])/c;9 e=1-d*d;8 F.13(c*F.1x(e<0?0:e))}},1h:l(a){9 b=7.1o(a);8(b!==w&&b<=17.16)},2T:l(a){8 a.1h(7)},1v:l(a){o(a.W){8 a.1v(7)}8(!7.1m(a)&&7.1o(a)<=17.16)},1U:l(a){o(a.W){8 a.1U(7)}o(!7.1v(a)){8 w}9 P=7.K.4,X=7.U.4,Q=a.K.4,Y=a.U.4;9 b=X[0],1z=X[1],1B=X[2],1T=Y[0],1S=Y[1],1M=Y[2];9 c=P[0]-Q[0],2s=P[1]-Q[1],2r=P[2]-Q[2];9 d=-b*c-1z*2s-1B*2r;9 e=1T*c+1S*2s+1M*2r;9 f=b*b+1z*1z+1B*1B;9 g=1T*1T+1S*1S+1M*1M;9 h=b*1T+1z*1S+1B*1M;9 k=(d*g/f+h*e)/(g-h*h);8 v.u([P[0]+k*b,P[1]+k*1z,P[2]+k*1B])},1r:l(a){o(a.U){o(7.1v(a)){8 7.1U(a)}o(7.1m(a)){8 w}9 D=7.U.4,E=a.U.4;9 b=D[0],1l=D[1],1k=D[2],1P=E[0],1O=E[1],1Q=E[2];9 x=(1k*1P-b*1Q),y=(b*1O-1l*1P),z=(1l*1Q-1k*1O);9 N=v.u([x*1Q-y*1O,y*1P-z*1Q,z*1O-x*1P]);9 P=11.u(a.K,N);8 P.1U(7)}1d{9 P=a.4||a;o(7.1h(P)){8 v.u(P)}9 A=7.K.4,D=7.U.4;9 b=D[0],1l=D[1],1k=D[2],1w=A[0],18=A[1],1a=A[2];9 x=b*(P[1]-18)-1l*(P[0]-1w),y=1l*((P[2]||0)-1a)-1k*(P[1]-18),z=1k*(P[0]-1w)-b*((P[2]||0)-1a);9 V=v.u([1l*x-1k*z,1k*y-b*x,b*z-1l*y]);9 k=7.1o(P)/V.1u();8 v.u([P[0]+V.4[0]*k,P[1]+V.4[1]*k,(P[2]||0)+V.4[2]*k])}},1V:l(t,a){o(1g(a.U)==\'1f\'){a=14.u(a.1N(),v.k)}9 R=S.1R(t,a.U).4;9 C=a.1r(7.K).4;9 A=7.K.4,D=7.U.4;9 b=C[0],1E=C[1],1J=C[2],1w=A[0],18=A[1],1a=A[2];9 x=1w-b,y=18-1E,z=1a-1J;8 14.u([b+R[0][0]*x+R[0][1]*y+R[0][2]*z,1E+R[1][0]*x+R[1][1]*y+R[1][2]*z,1J+R[2][0]*x+R[2][1]*y+R[2][2]*z],[R[0][0]*D[0]+R[0][1]*D[1]+R[0][2]*D[2],R[1][0]*D[0]+R[1][1]*D[1]+R[1][2]*D[2],R[2][0]*D[0]+R[2][1]*D[1]+R[2][2]*D[2]])},1t:l(a){o(a.W){9 A=7.K.4,D=7.U.4;9 b=A[0],18=A[1],1a=A[2],2N=D[0],1l=D[1],1k=D[2];9 c=7.K.1t(a).4;9 d=b+2N,2h=18+1l,2o=1a+1k;9 Q=a.1r([d,2h,2o]).4;9 e=[Q[0]+(Q[0]-d)-c[0],Q[1]+(Q[1]-2h)-c[1],Q[2]+(Q[2]-2o)-c[2]];8 14.u(c,e)}1d o(a.U){8 7.1V(F.1A,a)}1d{9 P=a.4||a;8 14.u(7.K.1t([P[0],P[1],(P[2]||0)]),7.U)}},1Z:l(a,b){a=v.u(a);b=v.u(b);o(a.4.q==2){a.4.19(0)}o(b.4.q==2){b.4.19(0)}o(a.4.q>3||b.4.q>3){8 w}9 c=b.1u();o(c===0){8 w}7.K=a;7.U=v.u([b.4[0]/c,b.4[1]/c,b.4[2]/c]);8 7}};14.u=l(a,b){9 L=25 14();8 L.1Z(a,b)};14.X=14.u(v.1j(3),v.i);14.Y=14.u(v.1j(3),v.j);14.Z=14.u(v.1j(3),v.k);l 11(){}11.23={24:l(a){8(7.1h(a.K)&&7.1m(a))},1q:l(){8 11.u(7.K,7.W)},2U:l(a){9 V=a.4||a;8 11.u([7.K.4[0]+V[0],7.K.4[1]+V[1],7.K.4[2]+(V[2]||0)],7.W)},1m:l(a){9 b;o(a.W){b=7.W.1C(a.W);8(F.13(b)<=17.16||F.13(F.1A-b)<=17.16)}1d o(a.U){8 7.W.2k(a.U)}8 w},2k:l(a){9 b=7.W.1C(a.W);8(F.13(F.1A/2-b)<=17.16)},1o:l(a){o(7.1v(a)||7.1h(a)){8 0}o(a.K){9 A=7.K.4,B=a.K.4,N=7.W.4;8 F.13((A[0]-B[0])*N[0]+(A[1]-B[1])*N[1]+(A[2]-B[2])*N[2])}1d{9 P=a.4||a;9 A=7.K.4,N=7.W.4;8 F.13((A[0]-P[0])*N[0]+(A[1]-P[1])*N[1]+(A[2]-(P[2]||0))*N[2])}},1h:l(a){o(a.W){8 w}o(a.U){8(7.1h(a.K)&&7.1h(a.K.2j(a.U)))}1d{9 P=a.4||a;9 A=7.K.4,N=7.W.4;9 b=F.13(N[0]*(A[0]-P[0])+N[1]*(A[1]-P[1])+N[2]*(A[2]-(P[2]||0)));8(b<=17.16)}},1v:l(a){o(1g(a.U)==\'1f\'&&1g(a.W)==\'1f\'){8 w}8!7.1m(a)},1U:l(a){o(!7.1v(a)){8 w}o(a.U){9 A=a.K.4,D=a.U.4,P=7.K.4,N=7.W.4;9 b=(N[0]*(P[0]-A[0])+N[1]*(P[1]-A[1])+N[2]*(P[2]-A[2]))/(N[0]*D[0]+N[1]*D[1]+N[2]*D[2]);8 v.u([A[0]+D[0]*b,A[1]+D[1]*b,A[2]+D[2]*b])}1d o(a.W){9 c=7.W.2f(a.W).2q();9 N=7.W.4,A=7.K.4,O=a.W.4,B=a.K.4;9 d=S.1j(2,2),i=0;H(d.2y()){i++;d=S.u([[N[i%3],N[(i+1)%3]],[O[i%3],O[(i+1)%3]]])}9 e=d.2w().4;9 x=N[0]*A[0]+N[1]*A[1]+N[2]*A[2];9 y=O[0]*B[0]+O[1]*B[1]+O[2]*B[2];9 f=[e[0][0]*x+e[0][1]*y,e[1][0]*x+e[1][1]*y];9 g=[];2e(9 j=1;j<=3;j++){g.19((i==j)?0:f[(j+(5-i)%3)%3])}8 14.u(g,c)}},1r:l(a){9 P=a.4||a;9 A=7.K.4,N=7.W.4;9 b=(A[0]-P[0])*N[0]+(A[1]-P[1])*N[1]+(A[2]-(P[2]||0))*N[2];8 v.u([P[0]+N[0]*b,P[1]+N[1]*b,(P[2]||0)+N[2]*b])},1V:l(t,a){9 R=S.1R(t,a.U).4;9 C=a.1r(7.K).4;9 A=7.K.4,N=7.W.4;9 b=C[0],1E=C[1],1J=C[2],1w=A[0],18=A[1],1a=A[2];9 x=1w-b,y=18-1E,z=1a-1J;8 11.u([b+R[0][0]*x+R[0][1]*y+R[0][2]*z,1E+R[1][0]*x+R[1][1]*y+R[1][2]*z,1J+R[2][0]*x+R[2][1]*y+R[2][2]*z],[R[0][0]*N[0]+R[0][1]*N[1]+R[0][2]*N[2],R[1][0]*N[0]+R[1][1]*N[1]+R[1][2]*N[2],R[2][0]*N[0]+R[2][1]*N[1]+R[2][2]*N[2]])},1t:l(a){o(a.W){9 A=7.K.4,N=7.W.4;9 b=A[0],18=A[1],1a=A[2],2M=N[0],2L=N[1],2Q=N[2];9 c=7.K.1t(a).4;9 d=b+2M,2p=18+2L,2m=1a+2Q;9 Q=a.1r([d,2p,2m]).4;9 e=[Q[0]+(Q[0]-d)-c[0],Q[1]+(Q[1]-2p)-c[1],Q[2]+(Q[2]-2m)-c[2]];8 11.u(c,e)}1d o(a.U){8 7.1V(F.1A,a)}1d{9 P=a.4||a;8 11.u(7.K.1t([P[0],P[1],(P[2]||0)]),7.W)}},1Z:l(a,b,c){a=v.u(a);a=a.1N();o(a===w){8 w}b=v.u(b);b=b.1N();o(b===w){8 w}o(1g(c)==\'1f\'){c=w}1d{c=v.u(c);c=c.1N();o(c===w){8 w}}9 d=a.4[0],18=a.4[1],1a=a.4[2];9 e=b.4[0],1W=b.4[1],1X=b.4[2];9 f,1i;o(c!==w){9 g=c.4[0],2l=c.4[1],2t=c.4[2];f=v.u([(1W-18)*(2t-1a)-(1X-1a)*(2l-18),(1X-1a)*(g-d)-(e-d)*(2t-1a),(e-d)*(2l-18)-(1W-18)*(g-d)]);1i=f.1u();o(1i===0){8 w}f=v.u([f.4[0]/1i,f.4[1]/1i,f.4[2]/1i])}1d{1i=F.1x(e*e+1W*1W+1X*1X);o(1i===0){8 w}f=v.u([b.4[0]/1i,b.4[1]/1i,b.4[2]/1i])}7.K=a;7.W=f;8 7}};11.u=l(a,b,c){9 P=25 11();8 P.1Z(a,b,c)};11.2I=11.u(v.1j(3),v.k);11.2H=11.u(v.1j(3),v.i);11.2G=11.u(v.1j(3),v.j);11.36=11.2I;11.35=11.2H;11.3j=11.2G;9 $V=v.u;9 $M=S.u;9 $L=14.u;9 $P=11.u;',62,206,'||||elements|||this|return|var||||||||||||function|||if||length||||create|Vector|null|||||||||Math|nj|while||do|anchor||||||||Matrix||direction||normal||||kj|Plane|ni|abs|Line|ki|precision|Sylvester|A2|push|A3|map|els|else||undefined|typeof|contains|mod|Zero|D3|D2|isParallelTo|kp|distanceFrom|cols|dup|pointClosestTo|np|reflectionIn|modulus|intersects|A1|sqrt|isSquare|X2|PI|X3|angleFrom|mod1|C2|mod2|sin|cos|break|C3|toRightTriangular|false|Y3|to3D|E2|E1|E3|Rotation|Y2|Y1|intersectionWith|rotate|v12|v13|rank|setVectors|nc|sum|multiply|prototype|eql|new|setElements|case|each|PA3|PA2|part|new_element|round|for|cross|product|AD2|isSameSizeAs|add|isPerpendicularTo|v22|AN3|inspect|AD3|AN2|toUnitVector|PsubQ3|PsubQ2|v23|dot|divisor|inverse|true|isSingular|determinant|max|canMultiplyFromLeft|subtract|rows|col|random|ZX|YZ|XY|Random|join|N2|N1|D1|slice|default|N3|dimensions|switch|liesIn|translate|snapTo|augment|Diagonal|trace|indexOf|diagonal|transpose|minor|row|isAntiparallelTo|ZY|YX|acos|RotationZ|RotationY|liesOn|RotationX|inv|rk|tr|det|toDiagonalMatrix|toUpperTriangular|version|XZ'.split('|'),0,{}))
 
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: pomegranate
3
  Tags: woocommerce, print, pdf, bulk, packing slips, invoices, delivery notes, invoice, packing slip, export, email
4
  Requires at least: 3.5 and WooCommerce 2.0
5
  Tested up to: 3.8 and WooCommerce 2.1
6
- Stable tag: 1.1.2
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
@@ -57,6 +57,23 @@ Copy the files from `woocommerce-pdf-invoices-packing-slips/templates/pdf/Simple
57
 
58
  Go to [wpovernight.com](https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-premium-templates/) to checkout more templates! These include templates with more tax details and product thumbnails. Need a custom templates? Contact us at support@wpovernight.com for more information.
59
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  == Screenshots ==
61
 
62
  1. General settings page
@@ -66,6 +83,11 @@ Go to [wpovernight.com](https://wpovernight.com/downloads/woocommerce-pdf-invoic
66
 
67
  == Changelog ==
68
 
 
 
 
 
 
69
  = 1.1.2 =
70
  * Feature: Totals can now be called with simpler template functions
71
  * Feature: Italian translations - thanks max66max!
3
  Tags: woocommerce, print, pdf, bulk, packing slips, invoices, delivery notes, invoice, packing slip, export, email
4
  Requires at least: 3.5 and WooCommerce 2.0
5
  Tested up to: 3.8 and WooCommerce 2.1
6
+ Stable tag: 1.1.3
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
57
 
58
  Go to [wpovernight.com](https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-premium-templates/) to checkout more templates! These include templates with more tax details and product thumbnails. Need a custom templates? Contact us at support@wpovernight.com for more information.
59
 
60
+ = My language is not included, how can I contribute? =
61
+
62
+ This plugin is translation ready, which means that you can translate it using standard WordPress methods.
63
+
64
+ 1. Download POEdit at (http://www.poedit.net/download.php)
65
+ 2. Open POEdit
66
+ 3. File > New from POT
67
+ 4. Open wpo_wcpdf.pot (from `woocommerce-pdf-invoices-packing-slips/languages/`)
68
+ 5. A popup will ask you for your language
69
+ 6. This step is a bit tricky, configuring the plurals. Somehow the settings can't be copied from the pot. Go to Catalogue > Preferences. Then enter nplurals=2; plural=n != 1; in the custom expression field
70
+ 7. Enter the translations. invoice and packing-slip now have two translation fields, single & plural. Note that this is a filename, so replace spaces with a - just to be sure!
71
+ 8. Save as `wpo_wcpdf-xx_XX.po`, where you replace xx_XX with your language code & country code suffix (da_DK, pl_PL, de_DE etc.)
72
+
73
+ = Fatal error: Allowed memory size of ######## bytes exhausted (tried to allocate ### bytes) =
74
+
75
+ This usually only happens on batch actions. PDF creation is a memory intensive job, especially if it includes several pages with images. Go to WooCommerce > System Status to check your WP Memory Limit. We recommend setting it to 128mb or more.
76
+
77
  == Screenshots ==
78
 
79
  1. General settings page
83
 
84
  == Changelog ==
85
 
86
+ = 1.1.3 =
87
+ * Feature: PDF engine (dompdf) updated to 0.6.0 for better stability and utf-8 support.
88
+ * Tweak: Local server path is used for header image for better compatibility with server settings.
89
+ * Fix: several small bugs.
90
+
91
  = 1.1.2 =
92
  * Feature: Totals can now be called with simpler template functions
93
  * Feature: Italian translations - thanks max66max!
woocommerce-pdf-invoices-packingslips.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: WooCommerce PDF Invoices & Packing Slips
4
  * Plugin URI: http://www.wpovernight.com
5
  * Description: Create, print & email PDF invoices & packing slips for WooCommerce orders.
6
- * Version: 1.1.2
7
  * Author: Ewout Fernhout
8
  * Author URI: http://www.wpovernight.com
9
  * License: GPLv2 or later
@@ -142,8 +142,16 @@ if ( !class_exists( 'WooCommerce_PDF_Invoices' ) ) {
142
  $attachment_src = $attachment[0];
143
  $attachment_width = $attachment[1];
144
  $attachment_height = $attachment[2];
 
 
 
 
 
 
 
 
145
 
146
- printf('<img src="%1$s" width="%2$d" height="%3$d" alt="%4$s" />', $attachment_src, $attachment_width, $attachment_height, esc_attr( $company ) );
147
  }
148
  }
149
  }
3
  * Plugin Name: WooCommerce PDF Invoices & Packing Slips
4
  * Plugin URI: http://www.wpovernight.com
5
  * Description: Create, print & email PDF invoices & packing slips for WooCommerce orders.
6
+ * Version: 1.1.3
7
  * Author: Ewout Fernhout
8
  * Author URI: http://www.wpovernight.com
9
  * License: GPLv2 or later
142
  $attachment_src = $attachment[0];
143
  $attachment_width = $attachment[1];
144
  $attachment_height = $attachment[2];
145
+
146
+ if (apply_filters('wpo_wcpdf_use_path', true)) {
147
+ $src = get_attached_file( $attachment_id );
148
+ } else {
149
+ $src = $attachment_src;
150
+ }
151
+
152
+ $attachment_path =
153
 
154
+ printf('<img src="%1$s" width="%2$d" height="%3$d" alt="%4$s" />', $src, $attachment_width, $attachment_height, esc_attr( $company ) );
155
  }
156
  }
157
  }