Changeset 20747 for lang/php

Show
Ignore:
Timestamp:
10/05/08 04:46:22 (2 months ago)
Author:
yudoufu
Message:

create css adding method

Location:
lang/php/HTML_CSS_Mobile/trunk
Files:
3 added
2 modified

Legend:

Unmodified
Added
Removed
  • lang/php/HTML_CSS_Mobile/trunk/HTML/CSS/Mobile.php

    r17637 r20747  
    33 * HTML_CSS_Mobile.php 
    44 * 
    5  * @author Daichi Kamemoto <daichi@asial.co.jp> 
     5 * @author Daichi Kamemoto <daikame@gmail.com> 
    66 */ 
    77/** 
    88 * The MIT License 
    99 * 
    10  * Copyright (c) 2008 Asial Corporation Japan, Daichi Kamemoto <daichi@asial.co.jp> 
     10 * Copyright (c) 2008 Daichi Kamemoto <daikame@gmail.com> 
    1111 * 
    1212 * Permission is hereby granted, free of charge, to any person obtaining a copy 
     
    3939 * 
    4040 * @author Daichi Kamemoto 
    41  * @version 0.1.4 
     41 * @version 0.1.5 
    4242 */ 
    4343class HTML_CSS_Mobile 
     
    4545        private $base_dir = './'; 
    4646        private $mode = 'transit'; // mode-> transit: Exception抑制 strict: 例外発生 
     47        private $dom; 
     48        private $dom_xpath; 
     49        private $css_files = array(); 
     50        private $html_css = array(); 
    4751 
    4852        /** 
     
    7276                return $this; 
    7377        } 
     78 
     79        /** 
     80         * CSSのファイルをプログラム側から読み込む 
     81         */ 
     82        public function addCSSFiles($files) 
     83        { 
     84                if (!is_array($files)) 
     85                { 
     86                        $files = array($files); 
     87                } 
     88 
     89                foreach ($files as $key => $file) 
     90                { 
     91                        if (substr($file, 0, 1) != '/') 
     92                        { 
     93                                $file = $this->base_dir . $file; 
     94                        } 
     95 
     96                        if (file_exists($file) && is_file($file)) 
     97                        { 
     98                                array_push($this->css_files, $file); 
     99                        } 
     100                } 
     101                 
     102                return $this; 
     103        } 
     104 
     105 
    74106 
    75107        /** 
     
    82114        public function apply($document, $base_dir = '') 
    83115        { 
     116                /**************************************** 
     117                 * 前処理 
     118                 ****************************************/ 
    84119                if (!$base_dir) 
    85120                { 
     
    119154                        $document = mb_convert_encoding($document, 'UTF-8', $doc_encoding); 
    120155                } 
     156                /**************************************** 
     157                 * 本処理  
     158                 ****************************************/ 
    121159 
    122160                // XHTMLをパース 
    123                 $dom = new DOMDocument(); 
    124                 $dom->loadHTML($document); 
    125                 $dom_xpath = new DOMXPath($dom); 
    126  
    127                 // 外部参照のCSSファイルを抽出する 
    128                 $nodes = $dom_xpath->query('//link[@rel="stylesheet" or @type="text/css"] | //style[@type="text/css"]'); 
     161                $this->dom = new DOMDocument(); 
     162                $this->dom->loadHTML($document); 
     163 
     164                $this->dom_xpath = new DOMXPath($this->dom); 
     165 
     166                $this->loadCSS(); 
    129167 
    130168                $add_style = array(); 
    131169                $psudo_classes = array('a:hover', 'a:link', 'a:focus', 'a:visited'); 
    132                 foreach ($nodes as $key => $node) 
    133                 { 
    134                         // CSSをパース 
    135                         #TODO: @importのサポート 
    136                         $html_css = new HTML_CSS(); 
    137                         if ($node->tagName == 'link' && $href = $node->attributes->getNamedItem('href')) 
    138                         { 
    139                                 // linkタグの場合 
    140                                 if (!file_exists($base_dir . $href->nodeValue)) 
    141                                 { 
    142                                         if ($this->mode == 'strict') 
    143                                         { 
    144                                                 throw new UnexpectedValueException('ERROR: ' . $base_dir . $href->nodeValue . ' file does not exist'); 
    145                                         } 
    146                                         else 
    147                                         { 
    148                                                 continue; 
    149                                         } 
    150                                 } 
    151  
    152                                 $css_string = file_get_contents($base_dir . $href->nodeValue); 
    153                         } 
    154                         else if ($node->tagName == 'style') 
    155                         { 
    156                                 // styleタグの場合 
    157                                 $css_string = $node->nodeValue; 
    158                         } 
    159  
    160                         // 文字コードをDOM利用のためにUTF-8化 
    161                         $css_encoding = mb_detect_encoding($css_string, 'UTF-8, eucjp-win, sjis-win,  iso-2022-jp'); 
    162                         if ($css_encoding != 'UTF-8') 
    163                         { 
    164                                 $css_string = mb_convert_encoding($css_string, 'UTF-8', $css_encoding); 
    165                         } 
    166  
    167                         $css_error = $html_css->parseString($css_string); 
    168                         if ($css_error)  
    169                         { 
    170                                 throw new RuntimeException('ERROR: css parse error'); 
    171                         } 
    172  
     170                foreach ($this->html_css as $html_css) 
     171                { 
    173172                        // a:hover, a:link, a:focus a:visited を退避 
    174173                        foreach ($psudo_classes as $psude_class) 
     
    190189 
    191190                                $xpath = selectorToXPath::toXPath($selector); 
    192                                 $elements = $dom_xpath->query($xpath); 
     191                                $elements = $this->dom_xpath->query($xpath); 
    193192 
    194193                                if ($elements->length == 0) continue; 
     
    217216                                } 
    218217                        } 
     218                } 
     219 
     220                // 疑似クラスを<style>タグとして追加 
     221                if (!empty($add_style)) 
     222                { 
     223                        $new_style = implode(PHP_EOL, $add_style); 
     224                        $new_style = implode(PHP_EOL, array('<![CDATA[', $new_style, ']]>')); 
     225 
     226                        $head = $this->dom_xpath->query('//head'); 
     227                        $new_style_node = new DOMElement('style', $new_style); 
     228                        $head->item(0)->appendChild($new_style_node)->setAttribute('type', 'text/css'); 
     229                } 
     230 
     231                $result = $this->dom->saveHTML(); 
     232 
     233                /**************************************** 
     234                 * 後処理 
     235                 ****************************************/ 
     236 
     237                // 文字コードを元に戻す 
     238                if ($doc_encoding != 'UTF-8') 
     239                { 
     240                        $result = mb_convert_encoding($result, $doc_encoding, 'UTF-8'); 
     241                        $result = str_replace(array('UTF-8', '@####UTF8####@'), array($html_encoding, 'UTF-8'), $result); 
     242                } 
     243 
     244                // エスケープしていた参照を復元 
     245                $result = preg_replace('/HTMLCSSINLINERESCAPE%(#\d+|\w+)%::::::::/', '&$1;', $result); 
     246 
     247                // 退避したXML宣言を復元 
     248                if (!empty($declaration)) 
     249                { 
     250                        $result = $declaration . $result; 
     251                } 
     252 
     253                return $result; 
     254        } 
     255 
     256        /** 
     257         * 各所で指定されているCSSファイルを読み込み、HTML_CSSのオブジェクト配列として格納する 
     258         */ 
     259        private function loadCSS() 
     260        { 
     261                // 外部参照のCSSファイルを抽出する 
     262                $nodes = $this->dom_xpath->query('//link[@rel="stylesheet" or @type="text/css"] | //style[@type="text/css"]'); 
     263 
     264                foreach ($nodes as $node) 
     265                { 
     266                        // CSSをパース 
     267                        #TODO: @importのサポート 
     268                        if ($node->tagName == 'link' && $href = $node->attributes->getNamedItem('href')) 
     269                        { 
     270                                // linkタグの場合 
     271                                if (!file_exists($base_dir . $href->nodeValue)) 
     272                                { 
     273                                        if ($this->mode == 'strict') 
     274                                        { 
     275                                                throw new UnexpectedValueException('ERROR: ' . $base_dir . $href->nodeValue . ' file does not exist'); 
     276                                        } 
     277                                        else 
     278                                        { 
     279                                                continue; 
     280                                        } 
     281                                } 
     282 
     283                                $css_string = file_get_contents($base_dir . $href->nodeValue); 
     284                        } 
     285                        else if ($node->tagName == 'style') 
     286                        { 
     287                                // styleタグの場合 
     288                                $css_string = $node->nodeValue; 
     289                        } 
     290 
     291                        $this->_loadCSS($css_string); 
    219292 
    220293                        // 読み込み終わったノードを削除。親ノードが取れない場合はスルー 
     
    223296                                $parent->removeChild($node); 
    224297                        } 
    225                 } 
    226  
    227                 // 疑似クラスを<style>タグとして追加 
    228                 if (!empty($add_style)) 
    229                 { 
    230                         $new_style = implode(PHP_EOL, $add_style); 
    231                         $new_style = implode(PHP_EOL, array('<![CDATA[', $new_style, ']]>')); 
    232  
    233                         $head = $dom_xpath->query('//head'); 
    234                         $new_style_node = new DOMElement('style', $new_style); 
    235                         $head->item(0)->appendChild($new_style_node)->setAttribute('type', 'text/css'); 
    236                 } 
    237  
    238                 $result = $dom->saveHTML(); 
    239  
    240                 // 文字コードを元に戻す 
    241                 if ($doc_encoding != 'UTF-8') 
    242                 { 
    243                         $result = mb_convert_encoding($result, $doc_encoding, 'UTF-8'); 
    244                         $result = str_replace(array('UTF-8', '@####UTF8####@'), array($html_encoding, 'UTF-8'), $result); 
    245                 } 
    246  
    247                 // エスケープしていた参照を復元 
    248                 $result = preg_replace('/HTMLCSSINLINERESCAPE%(#\d+|\w+)%::::::::/', '&$1;', $result); 
    249  
    250                 // 退避したXML宣言を復元 
    251                 if (!empty($declaration)) 
    252                 { 
    253                         $result = $declaration . $result; 
    254                 } 
    255  
    256                 return $result; 
     298 
     299                } 
     300 
     301                if (is_array($this->css_files)) 
     302                { 
     303                        foreach ($this->css_files as $file) 
     304                        { 
     305                                $css_string = ''; 
     306                                if (substr($file, 0, 1) != '/') 
     307                                { 
     308                                        $file = $this->base_dir . $file; 
     309                                } 
     310 
     311                                if (file_exists($file) && is_file($file)) 
     312                                { 
     313                                        $css_string = file_get_contents($file); 
     314                                        $this->_loadCSS($css_string); 
     315                                } 
     316                        } 
     317                } 
     318        } 
     319 
     320        private function _loadCSS($css_string) 
     321        { 
     322                // 文字コードをDOM利用のためにUTF-8化 
     323                $css_encoding = mb_detect_encoding($css_string, 'UTF-8, eucjp-win, sjis-win,  iso-2022-jp'); 
     324                if ($css_encoding != 'UTF-8') 
     325                { 
     326                        $css_string = mb_convert_encoding($css_string, 'UTF-8', $css_encoding); 
     327                } 
     328 
     329                $html_css = new HTML_CSS(); 
     330                $css_error = $html_css->parseString($css_string); 
     331                if ($css_error)  
     332                { 
     333                        throw new RuntimeException('ERROR: css parse error'); 
     334                } 
     335 
     336                $this->html_css[] = $html_css; 
    257337        } 
    258338} 
  • lang/php/HTML_CSS_Mobile/trunk/sample/sample.php

    r17637 r20747  
    44$document = file_get_contents('sample.html'); 
    55try { 
    6         echo HTML_CSS_Mobile::getInstance()->setBaseDir('./')->setMode('strict')->apply($document); 
     6        echo HTML_CSS_Mobile::getInstance()->setBaseDir('./')->setMode('strict')->addCSSFiles(array('sample3.css', 'sample4.css'))->addCSSFiles('sample5.css')->apply($document); 
    77} catch (RuntimeException $e) { 
    88        var_dump($e);